Skip to content

Most visited

Recently visited

navigation

Responding to Media Buttons

Media buttons are hardware buttons found on Android devices and other peripheral devices, for example, the pause/play button on a Bluetooth headset. When a user presses a media button, Android generates a KeyEvent, which contains a key code that identifies the button. The key codes for media button KeyEvents are constants that begin with KEYCODE_MEDIA (for example, KEYCODE_MEDIA_PLAY).

In order to handle media buttons, your app needs to set FLAG_HANDLES_MEDIA_BUTTONS when you initialize a media session.

When the user presses a media button your session receives a call to onMediaButtonEvent(). The default implementation extracts the key code and uses the media session's list of supported actions and current state to determine which method to call. For instance, KEYCODE_MEDIA_PLAY invokes onPlay(). In most cases, you do not need to override onMediaButtonEvent().

Android routes media button events in this order:

  1. Android first dispatches media button events to the foreground activity (the activity on the screen).
  2. If the activity does not handle the event, the system tries to send the event to an active media session. A media session becomes active when you call setActive(true). If there are multiple active media sessions, Android tries to choose a media session that is preparing to play (buffering/connecting), playing, or paused, rather than one that is stopped.
  3. If there is no active session, Android tries to send the event to the most recently active session. On Android 5.0 (API level 21) or later the event is only sent to sessions that have called setMediaButtonReceiver().

A KeyEvent generated by media button can pass through different components and the path depends on the version of Android that's running, as shown in the following diagram:

Your app must handle a media button events in three cases:

Handling media buttons in a UI activity

The foreground activity receives the media button key event in its onKeyDown() method.

If you are running Android 5.0 (API level 21) or later, call MediaControllerCompat.setMediaController() in MediaBrowserCompat.ConnectionCallback.onConnected. This causes onKeyDown() to automatically call your media controller's dispatchMediaButtonEvent(), which translates the key code to a media session callback.

Prior to Android 5.0 (API level 21), you need to modify onKeyDown() to handle the KeyEvent yourself. Intercept the play key code and call dispatchMediaButtonEvent(). Be sure to return true to indicate that the event was handled:

@Override
boolean onKeyDown(int keyCode, KeyEvent event) {
            switch (keyCode) {
            case KeyEvent.KEYCODE_MEDIA_PLAY:
                    yourMediaController.dispatchMediaButtonEvent(event);
                    return true;
            }
            return false;
    }

Handling media buttons in an active media session

On Android 5.0 (API level 21) and higher, Android automatically dispatches media button events to your active media session by calling onMediaButtonEvent(). By default this callback translates the KeyEvent into the appropriate media session Callback method that matches the key code.

Prior to Android 5.0 (API level 21), Android handles media button events by broadcasting an intent with the ACTION_MEDIA_BUTTON action. Your app must register a BroadcastReceiver to intercept these intents. The MediaButtonReceiver class was designed specifically for this purpose. It is a convenience class in the Android media-compat library that handles ACTION_MEDIA_BUTTON and translates the incoming Intents into the appropriate MediaSessionCompat.Callback method calls.

A MediaButtonReceiver is a short-lived BroadcastReceiver. It forwards incoming intents to the service that is managing your media session. If you want to use media buttons in systems earlier than Android 5.0 you must include the MediaButtonReceiver in your manifest with a MEDIA_BUTTON intent filter.:

<receiver android:name="android.support.v4.media.session.MediaButtonReceiver" >
   <intent-filter>
     <action android:name="android.intent.action.MEDIA_BUTTON" />
   </intent-filter>
 </receiver>

The BroadcastReceiver forwards the intent to your service. To parse the intent and generate the callback to your media session, include the MediaButtonReceiver.handleIntent() method in your service's onStartCommand(). This translates the key code into the appropriate session callback method.

private MediaSessionCompat mMediaSessionCompat = ...;

 public int onStartCommand(Intent intent, int flags, int startId) {
   MediaButtonReceiver.handleIntent(mMediaSessionCompat, intent);
   return super.onStartCommand(intent, flags, startId);
 }

Using media buttons to restart an inactive media session

If Android can identify the last active media session, it tries to restart the session by sending an ACTION_MEDIA_BUTTON Intent to a manifest-registered component (such as a service or BroadcastReceiver).

This lets your app restart playback while its UI is not visible, which is the case for most audio apps.

This behavior is automatically enabled when you use MediaSessionCompat. If you use the Android framework's MediaSession or Support Library 24.0.0 through 25.1.1 you must call setMediaButtonReceiver to let a media button restart an inactive media session.

You can disable this behavior in Android 5.0 (API level 21) and higher by setting a null media button receiver:

    // Create a MediaSessionCompat
    mMediaSession = new MediaSessionCompat(context, LOG_TAG);
    mMediaSession.setMediaButtonReceiver(null);

Customizing media button handlers

The default behavior for onMediaButtonEvent() extracts the key code and uses the media session's current state and list of supported actions to determine which method to call. For instance, KEYCODE_MEDIA_PLAY invokes onPlay().

To provide a consistent media button experience across all apps, you should use the default behavior and only deviate for a specific purpose. If a media button needs custom handling, override your callback’s onMediaButtonEvent() method, extract the KeyEvent using intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT), handle the event yourself, and return true.

Summary

To properly handle media button events in all versions of Android, you must specify FLAG_HANDLES_MEDIA_BUTTONS when you create a media session.

In addition, depending on the Android versions you plan to support, you must also meet these requirements:

When running in Android 5.0 or later:

When running in systems earlier than Android 5.0:

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.