问题
I have a Service which I use ExoPlayer to play music in it. I am displaying a notification for my app as it is a Foreground Service and I keep updating Notification in onPlayerStateChanged callback method of ExoPlayer :
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
...
showNotification(state, sample);
}
private void showNotification(PlaybackStateCompat state, Sample sample) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "Id");
int icon;
String play_pause;
if (state.getState() == PlaybackStateCompat.STATE_PLAYING) {
icon = R.drawable.exo_controls_pause;
play_pause = getString(R.string.pause);
} else {
icon = R.drawable.exo_controls_play;
play_pause = getString(R.string.play);
}
NotificationCompat.Action playPauseAction = new NotificationCompat.Action(
icon, play_pause,
MediaButtonReceiver.buildMediaButtonPendingIntent(this,
PlaybackStateCompat.ACTION_PLAY_PAUSE));
NotificationCompat.Action restartAction = new NotificationCompat
.Action(R.drawable.exo_controls_previous, getString(R.string.restart),
MediaButtonReceiver.buildMediaButtonPendingIntent
(this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS));
NotificationCompat.Action nextAction = new NotificationCompat
.Action(R.drawable.exo_controls_next, getString(R.string.next),
MediaButtonReceiver.buildMediaButtonPendingIntent
(this, PlaybackStateCompat.ACTION_SKIP_TO_NEXT));
PendingIntent contentPendingIntent = PendingIntent.getActivity
(this, 0, new Intent(this, MainActivity.class), 0);
Intent intent = new Intent(this, StopServiceBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
builder.setContentTitle(sample.getTitle())
.setContentText(sample.getComposer())
.setContentIntent(contentPendingIntent)
.setDeleteIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_music_note)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.addAction(restartAction)
.addAction(playPauseAction)
.addAction(nextAction).setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mMediaSession.getSessionToken())
.setShowActionsInCompactView(1, 2));
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "Id";
NotificationChannel channel = new NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_LOW);
mNotificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
Notification notificationCompat = builder.build();
if (state.getState() == PlaybackStateCompat.STATE_PAUSED) {
stopForeground(false);
mNotificationManager.notify(NOTIFICATION_ID, notificationCompat);
} else {
startForeground(NOTIFICATION_ID, notificationCompat);
}
}
As you see at the end of the method when state is PAUSE
, I stopForeground
. This will destroy Service within a minute, and as a result notification will be dismissed as discussed in following thread : https://github.com/google/ExoPlayer/issues/5954
I am a user of SoundCloud app. In their app, it seems that when state is PAUSE
, they have also stopForeground
since notification is dismissible. But if I do not dismiss notification manually, notification stays in status bar for always, and it seems Service is not destroyed in their app. The scenario that I explained for SoundCloud is just a guess
Do you think how it has been implemented in their app?
If something need to be checked, full source code of my sample can be found here : https://github.com/Ali-Rezaei/ExoPlayerSample
/**
* Release ExoPlayer.
*/
private void releasePlayer() {
mExoPlayer.removeListener(this);
mExoPlayer.stop();
mExoPlayer.release();
mExoPlayer = null;
}
/**
* Release the player when the service is destroyed.
*/
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy()");
super.onDestroy();
releasePlayer();
mMediaSession.setActive(false);
}
来源:https://stackoverflow.com/questions/62353553/can-we-avoid-stopforeground-to-stop-service