For mediaplayer, ACTION_SKIP_TO_NEXT
and ACTION_SKIP_TO_PREVIOUS
both are working fine from notification buttons for android 12 and below.
it seems that android 13 has a different behavior according to this.
to be clear, below buttons in the pictures are not working in android 13 only.
Android developer mentioned that playbackstate should be used for android 13
"For apps targeting Android 13 (API level 33) and higher, the system derives media controls from PlaybackState actions."
the problem is that in android 13 playstechange is never called, even public int onStartCommand
is never called.
tried below code but even no use
ComponentName receiver = new ComponentName(this, MediaButtonReceiver.class);
mediaSession = new MediaSessionCompat(getApplicationContext(), "MediaSession", receiver, null);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PAUSED, 0, 0)
.setActions(PlaybackStateCompat.ACTION_PLAY_PAUSE)
.setActions(PlaybackStateCompat.ACTION_SKIP_TO_NEXT) .setActions(PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
.build());
mediaSession.setActive(true);
mediaSession.setCallback(new MediaSessionCompat.Callback() {
// Implement callbacks
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
final String intentAction = mediaButtonEvent.getAction();
if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
final KeyEvent event = mediaButtonEvent.getParcelableExtra(
Intent.EXTRA_KEY_EVENT);
if (event == null) {
return super.onMediaButtonEvent(mediaButtonEvent);
}
final int keycode = event.getKeyCode();
final int action = event.getAction();
if (event.getRepeatCount() == 0 && action == KeyEvent.ACTION_DOWN) {
switch (keycode) {
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (mediaPlayer != null) {
if (isPlaying()) {
playbackAction(1);
pauseMedia();
updateMetaData();
} else { // want to continue playing
playbackAction(0);
playMedia();
}
}
break;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
pauseMedia();
break;
case KeyEvent.KEYCODE_MEDIA_PLAY:
process_play_request();
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
skipToPrevious();
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
skipToNext();
break;
}
}
}
return super.onMediaButtonEvent(mediaButtonEvent);
}});
and tried to add this code, but also no use:
MediaControllerCompat mController;
mController = new MediaControllerCompat(this, mediaSession.getSessionToken());
mController.registerCallback(mCallback);
mCallback.onPlaybackStateChanged(mController.getPlaybackState());
mCallback.onMetadataChanged(mController.getMetadata());
private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
@Override
public void onPlaybackStateChanged(PlaybackStateCompat playbackState) {
onUpdate();
}
@Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
onUpdate();
}
@Override
public void onSessionDestroyed() {
}
private void onUpdate() {
}
};
This issue has no relation to android.permission.POST_NOTIFICATIONS
as runtime permission is requested and granted but still no use.
Noting that after media player perpared, SetState is called as below:
mediaPlayer.start();
setState(PlaybackStateCompat.STATE_PLAYING);
private void setState(int state) {
long position = 0;
PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder();
builder.setState(state, position, 1.0f);
builder.setActions(
PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_STOP |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
PlaybackStateCompat.ACTION_SKIP_TO_NEXT);
mediaSession.setPlaybackState(builder.build());
}
suggestions please
Please try to add a few override methods to your MediaSessionCompat.Callback()
:
mediaSession.setCallback(new MediaSessionCompat.Callback() {
// Implement callbacks
@Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
// your implements
}
@Override
public void onPlay() {
super.onPlay();
// your play() implements
}
@Override
public void onPause() {
super.onPause();
// your pause() implements
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
// your next() implements
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
// your prev() implements
}
@Override
public void onSeekTo(long pos) {
// your seek() implements
}
});
You will receive the action buttons event in these callbacks.