在我正在使用的android应用中,我实现了MediaPlayer服务类(PlayService.java),该类将播放来自远程源的实时广播音频流。当服务在前台运行时,它将显示带有播放/暂停媒体传输控制的通知,以便用户也可以从那里处理媒体播放器的操作。我可以成功完成所有操作,但是我面临的唯一问题是,当用户从通知区域清除该通知时,该通知将被撤消,但该服务不会停止。我进行了大量研究,但找不到任何合适的解决方案。 我的MediaPlayer Service类的工作代码是:
public class PlayService extends Service implements MediaPlayer.OnCompletionListener,MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener,MediaPlayer.OnSeekCompleteListener,MediaPlayer.OnInfoListener,
MediaPlayer.OnBufferingUpdateListener,AudioManager.OnAudioFocusChangeListener {
private AudioManager audioManager;
private MediaPlayer mediaPlayer = new MediaPlayer();
private String sentAudioLink="";
//Used to pause/resume MediaPlayer
private int resumePosition;
//Handle notification in system tray
private NotificationCompat.Builder builder;
private NotificationManager notificationManager;
private int notification_id;
private RemoteViews remoteViews;
public static final String ACTION_PLAY = "com.example.ACTION_PLAY";
public static final String ACTION_PAUSE = "com.example.ACTION_PAUSE";
public static final String ACTION_STOP = "com.example.ACTION_STOP";
//MediaSession
private MediaSessionManager mediaSessionManager;
private MediaSessionCompat mediaSession;
private MediaControllerCompat.TransportControls transportControls;
//AudioPlayer notification ID
private static final int NOTIFICATION_ID = 101;
@Override
public void onCreate() {
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.reset();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle bundle = intent.getExtras();
if (bundle != null)
{
sentAudioLink = intent.getExtras().getString("sentAudioLink");
}
mediaPlayer.reset();
//setup the media player data source using the strAudioLink value
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.setDataSource(sentAudioLink);
//prepare media player
mediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
Log.e("workingerror1", e.toString());
stopSelf();
} catch (IllegalArgumentException e) {
Log.e("workingerror2", e.toString());
stopSelf();
} catch (IOException e) {
Log.e("workingerror3", e.toString());
stopSelf();
}
buildNotification(PlaybackStatus.PLAYING);
}
//Handle Intent action from MediaSession.TransportControls
handleIncomingActions(intent);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
removeNotification();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
@Override
public void onCompletion(MediaPlayer mp) {
stopMedia();
stopSelf();
buildNotification(PlaybackStatus.PAUSED);
}
public void stopMedia() {
if (mediaPlayer.isPlaying())
mediaPlayer.stop();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public void onPrepared(MediaPlayer mp) {
playMedia();
}
public void playMedia() {
if (!mediaPlayer.isPlaying() && sentAudioLink!="") {
mediaPlayer.start();
}
}
@Override
public void onSeekComplete(MediaPlayer mp) {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void buildNotification(PlaybackStatus playbackStatus) {
int notificationAction = android.R.drawable.ic_media_pause;//needs to be initialized
PendingIntent play_pauseAction = null;
//Build a new notification according to the current state of the MediaPlayer
if (playbackStatus == PlaybackStatus.PLAYING) {
notificationAction = android.R.drawable.ic_media_pause;
//create the pause action
play_pauseAction = playbackAction(1);
} else if (playbackStatus == PlaybackStatus.PAUSED) {
notificationAction = android.R.drawable.ic_media_play;
//create the play action
play_pauseAction = playbackAction(0);
}
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.uow_logo); //replace with your own image
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,CHANNEL_ID)
.setShowWhen(false)
// Set the Notification style
.setStyle(new MediaStyle()
// Show our playback controls in the compact notification view.
.setShowActionsInCompactView(0)
.setShowCancelButton(true)
.setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(
this, PlaybackStateCompat.ACTION_STOP)))
// Set the Notification color
.setColor(getResources().getColor(R.color.colorPrimary))
// Set the large and small icons
.setSmallIcon(R.drawable.uow_logo)
.setLargeIcon(largeIcon)
// Set Notification content information
.setContentText("FM Radia - 101.8")
.setContentTitle("University of Wah")
.setOngoing(true)
.setAutoCancel(false)
// Add playback actions
.addAction(notificationAction, "pause", play_pauseAction)
.setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(
this, PlaybackStateCompat.ACTION_STOP));
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notificationBuilder.build());
}
private void removeNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NOTIFICATION_ID);
}
private PendingIntent playbackAction(int actionNumber) {
Intent playbackAction = new Intent(this, PlayService.class);
switch (actionNumber) {
case 0:
// Play
playbackAction.setAction(ACTION_PLAY);
return PendingIntent.getService(this, actionNumber, playbackAction, 0);
case 1:
// Pause
playbackAction.setAction(ACTION_PAUSE);
return PendingIntent.getService(this, actionNumber, playbackAction, 0);
default:
break;
}
return null;
}
private void handleIncomingActions(Intent playbackAction)
{
if (playbackAction == null || playbackAction.getAction() == null) return;
String actionString = playbackAction.getAction();
Log.e("actionString",actionString);
if (actionString.equalsIgnoreCase(ACTION_PLAY))
{
//Play the music
}
else if (actionString.equalsIgnoreCase(ACTION_PAUSE))
{
if (mediaPlayer.isPlaying())
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
buildNotification(PlaybackStatus.PAUSED);
stopSelf();
}
else(actionString.equalsIgnoreCase(ACTION_STOP))
{
if (mediaPlayer != null) {
removeNotification();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
}
}
}