当应用程序进入后台时,MediaBrowserServiceCompat 停止播放音乐

时间:2020-12-22 02:49:03

标签: android exoplayer mediabrowserservicecompat

当应用进入后台时,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, 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();
}

1 个答案:

答案 0 :(得分:0)

在浪费了 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();
}