问题描述
当应用进入后台时,Mediabrowsercompat 不播放音乐。如果我没有在活动 onStop 方法中断开 mediabrowsercompat 实例,那么它正在工作。但这不是解决方案,因为根据文档,一旦应用进入后台,我们就必须断开服务。
这是我的 mediabrowserservicecomat 类(我使用 Exoplayer 播放音乐):
private static final String PLAYBACK_CHANNEL_ID = "100";
private static final int PLAYBACK_NOTIFICATION_ID =101 ;
private MediaSessionCompat mediaSessionCompat;
private PlaybackStateCompat.Builder stateBuilder;
private SimpleExoPlayer exoPlayer;
private Uri oldUri;
private AudioAttributes audioAttributes;
private Playernotificationmanager playernotificationmanager;
@Override
public void onCreate() {
super.onCreate();
Log.i("Test","Hi");
initPlayer();
initAttributes();
ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(),MediaButtonReceiver.class);
mediaSessionCompat = new MediaSessionCompat(getApplicationContext(),"Tag",mediaButtonReceiver,null);
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS|
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
stateBuilder = new PlaybackStateCompat.Builder();
stateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY|PlaybackStateCompat.ACTION_PLAY_PAUSE);
mediaSessionCompat.setPlaybackState(stateBuilder.build());
mediaSessionCompat.setCallback(mediaSessionCompatCallback);
setSessionToken(mediaSessionCompat.getSessionToken());
mediaSessionCompat.setActive(true);
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setClass(this,MediaButtonReceiver.class);
PendingIntent pendingIntent = PendingIntent.getbroadcast(this,mediaButtonIntent,0);
mediaSessionCompat.setMediaButtonReceiver(pendingIntent);
}
@Override
public int onStartCommand(Intent intent,int flags,int startId) {
MediaButtonReceiver.handleIntent(mediaSessionCompat,intent);
return super.onStartCommand(intent,flags,startId);
}
private MediaSessionCompat.Callback mediaSessionCompatCallback = new MediaSessionCompat.Callback() {
@Override
public void onPlayFromUri(Uri uri,Bundle extras) {
super.onPlayFromUri(uri,extras);
if (uri!=null){
MediaItem mediaSource = MediaItem.fromUri(uri);
if (uri!=oldUri){
play(mediaSource);
onPlay();
}else {
oldUri = uri;
}
}
}
@Override
public void onPlay() {
super.onPlay();
Log.i("onPlay","onPlay");
//startService(new Intent(MusicService.this,MusicForegroundService.class));
playernotificationmanager = Playernotificationmanager.createWithNotificationChannel(MusicService.this,PLAYBACK_CHANNEL_ID,R.string.channel_name,PLAYBACK_NOTIFICATION_ID,new Playernotificationmanager.MediaDescriptionAdapter() {
@Override
public CharSequence getCurrentContentTitle(Player player) {
return "title";
}
@Nullable
@Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(getBaseContext(),PlayerFullViewActivity.class);
return PendingIntent.getActivity(getBaseContext(),intent,PendingIntent.FLAG_UPDATE_CURRENT);
}
@Nullable
@Override
public CharSequence getCurrentContentText(Player player) {
return "content";
}
@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player,Playernotificationmanager.BitmapCallback callback) {
return null;
}
},new Playernotificationmanager.NotificationListener() {
@Override
public void onNotificationPosted(int notificationId,Notification notification,boolean ongoing) {
startForeground(notificationId,notification);
}
@Override
public void onNotificationCancelled(int notificationId,boolean dismissedByUser) {
stopSelf();
}
});
playernotificationmanager.setPlayer(exoPlayer);
}
@Override
public void onPause() {
super.onPause();
pause();
}
@Override
public void onStop() {
playernotificationmanager.setPlayer(null);
super.onStop();
stop();
}
};
@Override
public void onDestroy() {
super.onDestroy();
stop();
}
private void stop() {
exoPlayer.setPlayWhenReady(false);
exoPlayer.release();
exoPlayer =null;
updatePlayBackState(PlaybackStateCompat.STATE_NONE);
mediaSessionCompat.setActive(false);
mediaSessionCompat.release();
}
@SuppressLint("WrongConstant")
private void pause() {
if (exoPlayer!=null){
exoPlayer.setPlayWhenReady(false);
if (exoPlayer.getPlaybackState()==PlaybackStateCompat.STATE_PLAYING){
updatePlayBackState(PlaybackStateCompat.STATE_PAUSED);
}
}
}
private void play(MediaItem mediaSource){
if (exoPlayer==null) {
initPlayer();
}
if (audioAttributes==null) {
initAttributes();
}
exoPlayer.setAudioAttributes(audioAttributes,true);
exoPlayer.setMediaItem(mediaSource);
exoPlayer.prepare();
play();
}
private void initAttributes() {
audioAttributes = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build();
}
private void initPlayer() {
exoPlayer = new SimpleExoPlayer.Builder(this,new DefaultRenderersFactory(getBaseContext()),new DefaultExtractorsFactory()).build();
}
private void play() {
exoPlayer.setPlayWhenReady(true);
updatePlayBackState(PlaybackStateCompat.STATE_PLAYING);
mediaSessionCompat.setActive(true);
}
private void updatePlayBackState(int statePlaying) {
mediaSessionCompat.setPlaybackState(new PlaybackStateCompat.Builder().
setState(statePlaying,0L,0).build());
}
@Nullable
@Override
public browserRoot onGetRoot(@NonNull String clientPackageName,int clientUid,@Nullable Bundle rootHints) {
return new browserRoot("",null);
}
@Override
public void onLoadChildren(@NonNull String parentId,@NonNull Result<List<MediabrowserCompat.MediaItem>> result) {
result.sendResult(null);
}
这是我的活动课:
ActivityPlayerFullViewBinding activityPlayerFullViewBinding;
private MediabrowserCompat mediabrowserCompat;
private MediabrowserCompat.ConnectionCallback connectionCallback = new MediabrowserCompat.ConnectionCallback(){
@Override
public void onConnected() {
super.onConnected();
MediaSessionCompat.Token sessionToken = mediabrowserCompat.getSessionToken();
if (sessionToken!=null){
try {
MediaControllerCompat mediaControllerCompat = new
MediaControllerCompat(PlayerFullViewActivity.this,sessionToken);
MediaControllerCompat.setMediaController(PlayerFullViewActivity.this,mediaControllerCompat);
playPauseBuild();
Log.d("onConnected","ConnectionSuccess");
} catch (remoteexception e) {
e.printstacktrace();
}
}
}
@Override
public void onConnectionFailed() {
super.onConnectionFailed();
Log.d("onConnectionFaild","ConnectionFailed");
}
};
MediaControllerCompat.Callback controllerCallback =
new MediaControllerCompat.Callback() {
@Override
public void onMetadataChanged(MediaMetadataCompat Metadata) {}
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityPlayerFullViewBinding = DataBindingUtil.setContentView(this,R.layout.activity_player_full_view);
ComponentName componentName = new ComponentName(this,MusicService.class);
mediabrowserCompat = new MediabrowserCompat(this,componentName,connectionCallback,null);
}
private void playPauseBuild() {
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(PlayerFullViewActivity.this);
activityPlayerFullViewBinding.playPauseBtn
.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int state = mediaController.getPlaybackState().getState();
if (state== PlaybackStateCompat.STATE_PAUSED||state==PlaybackStateCompat.STATE_STOPPED||
state==PlaybackStateCompat.STATE_NONE){
mediaController.getTransportControls().playFromUri(
Uri.parse("https://www.mBoxdrive.com/Eminem-Sing-For-The-Moment9jamo.com_.mp3"),null);
activityPlayerFullViewBinding.playPauseBtn.setText("Pause");
}else if (state == PlaybackStateCompat.STATE_PLAYING ||
state == PlaybackStateCompat.STATE_BUFFERING ||
state == PlaybackStateCompat.STATE_CONNECTING){
mediaController.getTransportControls().pause();
activityPlayerFullViewBinding.playPauseBtn.setText("Play");
}
}
});
mediaController.registerCallback(controllerCallback);
}
@Override
protected void onStart() {
super.onStart();
mediabrowserCompat.connect();
}
@Override
public void onResume() {
super.onResume();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
@Override
protected void onStop() {
super.onStop();
Log.i("onStop","onStop");
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(this);
if (mediaController != null) {
mediaController.unregisterCallback(controllerCallback);
}
mediabrowserCompat.disconnect();
}
解决方法
在浪费了 2 个不眠之夜之后。我找到了一个解决方法。我不知道这是否是处理此问题的正确方法。但是如果你曾经遇到过这个问题。你可以试试:
@Override
protected void onStart() {
super.onStart();
if (!mediaBrowserCompat.isConnected())
mediaBrowserCompat.connect();
}
@Override
protected void onStop() {
super.onStop();
Log.i("onStop","onStop");
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(this);
if (mediaController != null) {
mediaController.unregisterCallback(controllerCallback);
}
// mediaBrowserCompat.disconnect();
}
@Override
protected void onDestroy() {
super.onDestroy();
mediaBrowserCompat.disconnect();
}