0

Mediabrowsercompat not playing the music when app goes background. If I don't disconnect the mediabrowsercompat instance in activity onStop method then it is working. But that is not the solution as according to documentation we have to disconnect the service once app goes background.

This is my mediabroweserservicecomat class (I am using Exoplayer to play music):

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);
}

This is my activity class:

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();
}
sum20156
  • 646
  • 1
  • 7
  • 19

1 Answers1

0

After wasting 2 sleepless nights. I found a workaround. I don't know whether it's a correct way to handle this. But if you have ever faced this problem. You can try it:

 @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();
}
sum20156
  • 646
  • 1
  • 7
  • 19