当应用程序进入后台时,Mediabrowsercompat 不播放音乐。如果我没有断开活动 onStop 方法中的 mediabrowsercompat 实例,那么它正在工作。但这不是解决方案,因为根据文档,一旦应用程序进入后台,我们必须断开服务。
这是我的 mediabroweserservicecomat 类(我正在使用 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, 0, 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(), 0, 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();
}