Receiving and handling button events
suggest changeThis example creates a MediaSession
object when a Service
is started. The MediaSession
object is released when the Service
gets destroyed:
public final class MyService extends Service { private static MediaSession s_mediaSession; @Override public void onCreate() { // Instantiate new MediaSession object. configureMediaSession(); } @Override public void onDestroy() { if (s_mediaSession != null) s_mediaSession.release(); } }
The following method instantiates and configures the MediaSession
button callbacks:
private void configureMediaSession { s_mediaSession = new MediaSession(this, "MyMediaSession"); // Overridden methods in the MediaSession.Callback class. s_mediaSession.setCallback(new MediaSession.Callback() { @Override public boolean onMediaButtonEvent(Intent mediaButtonIntent) { Log.d(TAG, "onMediaButtonEvent called: " + mediaButtonIntent); KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { int keyCode = ke.getKeyCode(); Log.d(TAG, "onMediaButtonEvent Received command: " + ke); } return super.onMediaButtonEvent(mediaButtonIntent); } @Override public void onSkipToNext() { Log.d(TAG, "onSkipToNext called (media button pressed)"); Toast.makeText(getApplicationContext(), "onSkipToNext called", Toast.LENGTH_SHORT).show(); skipToNextPlaylistItem(); // Handle this button press. super.onSkipToNext(); } @Override public void onSkipToPrevious() { Log.d(TAG, "onSkipToPrevious called (media button pressed)"); Toast.makeText(getApplicationContext(), "onSkipToPrevious called", Toast.LENGTH_SHORT).show(); skipToPreviousPlaylistItem(); // Handle this button press. super.onSkipToPrevious(); } @Override public void onPause() { Log.d(TAG, "onPause called (media button pressed)"); Toast.makeText(getApplicationContext(), "onPause called", Toast.LENGTH_SHORT).show(); mpPause(); // Pause the player. super.onPause(); } @Override public void onPlay() { Log.d(TAG, "onPlay called (media button pressed)"); mpStart(); // Start player/playback. super.onPlay(); } @Override public void onStop() { Log.d(TAG, "onStop called (media button pressed)"); mpReset(); // Stop and/or reset the player. super.onStop(); } }); s_mediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); s_mediaSession.setActive(true); }
The following method sends meta data (stored in a HashMap
) to the device using A2DP:
void sendMetaData(@NonNull final HashMap<String, String> hm) { // Return if Bluetooth A2DP is not in use. if (!((AudioManager) getSystemService(Context.AUDIO_SERVICE)).isBluetoothA2dpOn()) return; MediaMetadata metadata = new MediaMetadata.Builder() .putString(MediaMetadata.METADATA_KEY_TITLE, hm.get("Title")) .putString(MediaMetadata.METADATA_KEY_ALBUM, hm.get("Album")) .putString(MediaMetadata.METADATA_KEY_ARTIST, hm.get("Artist")) .putString(MediaMetadata.METADATA_KEY_AUTHOR, hm.get("Author")) .putString(MediaMetadata.METADATA_KEY_COMPOSER, hm.get("Composer")) .putString(MediaMetadata.METADATA_KEY_WRITER, hm.get("Writer")) .putString(MediaMetadata.METADATA_KEY_DATE, hm.get("Date")) .putString(MediaMetadata.METADATA_KEY_GENRE, hm.get("Genre")) .putLong(MediaMetadata.METADATA_KEY_YEAR, tryParse(hm.get("Year"))) .putLong(MediaMetadata.METADATA_KEY_DURATION, tryParse(hm.get("Raw Duration"))) .putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER, tryParse(hm.get("Track Number"))) .build(); s_mediaSession.setMetadata(metadata); }
The following method sets the PlaybackState
. It also sets which button actions the MediaSession
will respond to:
private void setPlaybackState(@NonNull final int stateValue) { PlaybackState state = new PlaybackState.Builder() .setActions(PlaybackState.ACTION_PLAY | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_SKIP_TO_PREVIOUS | PlaybackState.ACTION_STOP | PlaybackState.ACTION_PLAY_PAUSE) .setState(stateValue, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0) .build(); s_mediaSession.setPlaybackState(state); }
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents