8

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?

Hackmodford
  • 3,901
  • 4
  • 35
  • 78

1 Answers1

13

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.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Not setting the actions sounds plausible. I'll double check that. – Hackmodford Jul 07 '16 at 20:07
  • I missed setting the actions. Flags were automatic because I'm using MediaBrowserCompat Thank you so much! – Hackmodford Jul 07 '16 at 23:22
  • I'm not sure what you mean by 'Flags were automatic'? If you're not calling `setFlags()` there are certainly going to be issues (particularly on receiving media buttons on – ianhanniballake Jul 07 '16 at 23:36
  • You're right, I just realized that they do set them in their example. Thank You – Hackmodford Jul 08 '16 at 01:01
  • Damn you setActions() ! – timr Oct 29 '17 at 19:18
  • I didn't have `setActive(true)` cause their bloody docs don't mention it. – Vucko May 10 '20 at 14:31
  • @Vucko - it is specifically called out (with example code) on the [Media Session Callbacks documentation](https://developer.android.com/guide/topics/media-apps/audio-app/mediasession-callbacks), which details exactly when you should be calling it. – ianhanniballake May 10 '20 at 16:30
  • @ianhanniballake The docs are not the best, to put it mildly. I have followed them precisely and half of the things are not working. UAMP example is terribly complex and hard to read and navigate. Do you offer consulting, I'd be willing to pay for it, to help me create a pretty darn simple audio playing in the app ? – Vucko May 17 '20 at 14:15