MediaButtonReceiver not working with MediaBrowserServiceCompat
Asked Answered
R

1

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?

Rory answered 7/7, 2016 at 13:41 Comment(0)
S
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.

Stutman answered 7/7, 2016 at 19:42 Comment(8)
Not setting the actions sounds plausible. I'll double check that.Rory
I missed setting the actions. Flags were automatic because I'm using MediaBrowserCompat Thank you so much!Rory
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 <API 21 devices)Stutman
You're right, I just realized that they do set them in their example. Thank YouRory
Damn you setActions() !Loricate
I didn't have setActive(true) cause their bloody docs don't mention it.Bigeye
@Bigeye - it is specifically called out (with example code) on the Media Session Callbacks documentation, which details exactly when you should be calling it.Stutman
@Stutman 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 ?Bigeye

© 2022 - 2024 — McMap. All rights reserved.