Best practices in media playback - Google I/O 2016
Why Stack Overflow recommends it
Stack Overflow users, especially one frequent Android answerer, link it as the canonical reference for how to set up MediaSession, media button handling, MediaStyle notifications and foreground services in Android media apps.
Recommended by 1 people across 4 different months, 2016 to 2019.
What it is
A Google I/O 2016 talk from the Android Developers channel on building media playback apps correctly. It covers app architecture, local audio playback, remote playback, audio focus, MediaSession, MediaStyle notifications, foreground services, and support for Android Wear and Android Auto.
What people said
Strong rec ianhanniballake · 2016-06 · Stack Overflow · on “Changing Notification RemoteViews Background Color”
Much of this can be easier done by taking advantage of NotificationCompat.MediaStyle [LINK] . It pulls the background color from the setColor() [LINK] call on pre-API 24 devices (and uses that color as an accent on API 24+ devices). This also means you don't need to write any custom RemoteViews code anymore as it relies solely on the actions you add to your notification for media controls: NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this); nBuilder.setSmallIcon(R.drawable.not_icon) .setContentTitle(getCurrentSong().getTitle()) .setContentIntent(notOpenOnClick); // This is what sets the background color on <N devices // It is an accent color on N+ devices nBuilder.set
Recommends ianhanniballake · 2016-06 · Stack Overflow · on “How does doze mode affect background/foreground services, with/without partial/full wakelocks?”
Services that are not specifically a foreground service (i.e., they have not called startForeground [LINK] )) receive all of the restrictions that apply when dozed - they are not whitelisted. A music playback app should **always** be a foreground service when actively playing audio as per the Best Practices in Media Playback talk at I/O 2016 [this video] and are strongly recommended to be in a separate process (both because it is a good idea and the bug)
Recommends ianhanniballake · 2016-07 · Stack Overflow · on “MediaButtonReceiver not working with MediaBrowserServiceCompat”
As explained in the Best Practices in media playback I/O 2016 talk [this video] , 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) [LINK] 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() [this video] on your PlaybackStateCompat.Builder [LINK] 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.
Recommends ianhanniballake · 2016-09 · Stack Overflow · on “Android: Handle headset buttons events and Send information to MainActivity”
API 21 changed the entire media app APIs, now centering entirely around MediaSession [LINK] . Instead of registering a BroadcastReceiver (as was needed prior to API 18) or a PendingIntent (via registerMediaButtonEventReceiver(PendingIntent) [LINK] ), you can receive callbacks directly in the MediaSession.Callback [LINK] . You can set up a MediaSession via the following code: MediaSession.Callback callback = new MediaSession.Callback() { @Override public void onPlay() { // Handle the play button } }; MediaSession mediaSession = new MediaSession(context, TAG); // Debugging tag, any string mediaSession.setFlags( MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTR
Recommends ianhanniballake · 2016-10 · Stack Overflow · on “Make Action icons appear when notification is collapsed”
You need to use a MediaStyle notification [LINK] and use setShowActionsInCompactView() [LINK] to set which actions you want to appear in the compact, unexpanded view as explained in the Best practices in media playback talk [this video] from I/O 2016.
Recommends ianhanniballake · 2016-10 · Stack Overflow · on “Can I use Media Style notification with a podcast app I am developing using Exoplayer”
Yes, you can use a MediaStyle notification with ExoPlayer. In fact, you need to implement a number of Best practices in media playback [this video] including: Audio Focus the BECOMING_NOISY broadcast MediaSession a MediaStyle notification Service life cycle including being a foreground service Keeping your UI in sync ExoPlayer does not take care of any of those things for you.
Cites Lee Hounshell · 2016-06 · Stack Overflow · on “Universal Android Media Player - UAMP”
I believe you need to modify the model/RemoteJSONSource.java so that it adds MediaMetadataCompat items into the tracks ArrayList. You will need to create a ' buildFromJSON ' method that creates a MediaMetadataCompat object. Be sure to set as many of the media attributes as possible. The Google example shows media being added from a remote JSON source. In my case, I have already loaded remote Firebase JSON into a local SQLite database. So I load my media from SQLite instead. To do that I modified the buildFromJson to be buildFromEpisodesCursor and changed the guts appropriately. (Firebase can send JSON updates to SQLite if the media changes.) Here is a snippet with the key codeblocks: public
Cites Zaartha · 2019-11 · Stack Overflow · on “Catching android media button events”
As explained here [this video] you must call setActions() on your PlaybackStateCompat.Builder to tell exactly what actions you support - if you don't set that then you won't get any of the callbacks relating to media buttons. You are setting these actions in the callback which is why it's not working. .... private Handler handler; private PlaybackStateCompat.Builder mStateBuilder; ..... Add the following in onCreate. .... mediaSession = new MediaSessionCompat(this, "fpt2s"); mStateBuilder = new PlaybackStateCompat.Builder() .setActions( PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS | PlaybackStateCompat.ACTION_SKIP_TO_NEXT | Playb