androidheadsetandroid-mediasession

MediaButtonReceiver not working with MediaBrowserServiceCompat


I am trying to receive media button events from headsets or car controls (play/pause/etc.)

This is in my app manifest.

<service android:name=".mediaPlayerService.MediaPlayerService"
         android:exported="true">
    <intent-filter>
        <action android:name="android.media.browse.MediaBrowserService"/>
    </intent-filter>
</service>

<!--
A receiver that will receive media buttons and send as
intents to your MediaBrowserServiceCompat implementation.
Required on pre-Lollipop. More information at
http://developer.android.com/reference/android/support/v4/media/session/MediaButtonReceiver.html
-->
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_BUTTON"/>
    </intent-filter>
</receiver>

This is part of my MediaPlayerService

public class MediaPlayerService extends MediaBrowserServiceCompat {

@Override
public void onCreate()
{
    super.onCreate();
    initMediaSessions();
}

private void initMediaSessions()
{
    mSession = new MediaSessionCompat(getApplicationContext(), MediaPlayerService.class.getSimpleName());
    setSessionToken(mSession.getSessionToken());

    mSession.setCallback(new MediaSessionCompat.Callback()
                         {
                            //callback code is here.     
                         }            
    );
}

@Override
public int onStartCommand(Intent startIntent, int flags, int startId)
{
    if (startIntent != null)
    {
        // Try to handle the intent as a media button event wrapped by MediaButtonReceiver
        MediaButtonReceiver.handleIntent(mSession, startIntent);
    }
    return START_STICKY;
}

It seems like I'm missing something. When I press the pause button on my headset controls, the onStartCommand is never called.

Any idea why this is not working as expected?


Solution

  • As explained in the Best Practices in media playback I/O 2016 talk, you need to also call

    mSession.setFlags(
      MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
      MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
    

    when you construct your media session and before you start playback, you must call setActive(true) as per its documentation:

    You must set the session to active before it can start receiving media button events or transport commands.

    Note that you must also call setActions() on your PlaybackStateCompat.Builder to say exactly what actions you support - if you don't set that then you won't get any of the callbacks relating to media buttons.