Today's #AndroidDev #Protip by +Kristan Uccello is about being a good audio citizen.

A big part of being a good audio citizen on Android and providing expected audio behaviour for users is respecting audio focus to make sure that apps don't play audio over each other unexpectedly.

Playing audio in your app takes more than just instantiating a MediaPlayer and feeding it an audio source file. Before using the audio system, an app should request audio focus and assert that audio focus has been successfully granted to it. Note that it is NOT a good practice to simply request audio focus when your app starts. Instead, request focus as close as possible to the event or call that will actually use the audio system.

The APIs for audio focus are fairly simple. Apps can request audio focus from the AudioManager by calling requestAudioFocus [1] with an OnAudioFocusChangeListener and one of the "duration hint" [2] options describing whether this is for long-form or short-form (transient) audio playback. To abandon audio focus, simply call abandonAudioFocus. Note that the audio focus change listener has corresponding AUDIOFOCUS_GAIN and AUDIOFOCUS_LOSS events for the various duration hints.

For more details on properly handling audio focus, check out our new blog post on the topic here:

Respecting Audio Focus: http://goo.gl/etpTtM

As well as the relevant Android Training class:

Managing Audio Focus: http://goo.gl/5tJUX

····················

[1] requestAudioFocus: http://goo.gl/RCHDqP
[2] GAIN, GAIN_TRANSIENT, GAIN_TRANSIENT_MAY_DUCK: http://goo.gl/q0zZ3l
61
26
Gorancho Sirkarovski's profile photoQuang-Hai PHAN's profile photoTed Chien's profile photoibrahim abudheem's profile photo
19 comments
 
What a load of crap! If my app is designed to play music (or sfx) and user started it (or has it still running in the background) then it has full rights to play whatever it wants along with other apps in the same time (it was user decision to launch/install that app). onPause + onResume is for music maintenance (for ex. on incoming phone call). No need to make another layers of abstraction for such simple api.
 
Btw. If you G-guys are so bored and have too much time for reinventing the wheel, then do something useful and fix bluetooth api.
 
+Marcel Wesołowski actually I think it makes sense. If I'm playing music and have navigation active (common scenario when I'm driving), I want the navigation app to request focus (turn down/off the music) only when there's something that needs my attention.
 
Ok, but what if two or more running apps are requesting this in the same time? Which one is more important for the user, can you tell? It is much more important to NOT to change stream volume, because: 1) it is against what user set in device settings (or with volume buttons) and 2) may lead to missing important sound data from other apps (like the navigation app you mentioned). Proposed abstraction layer violates user's decisions by thinking what's better for him/her.
 
I still don't agree with you. If you provide an API to get audio focus, it is possible to block one of them while the other gives a notification (I'm not saying that this is the only option, I'm saying it allows for this). If you don't provide this API, you have lots of apps competing for sound at the same time, which is worse.
 
I'd also like to point an anti-pattern of media player which is YouTube app. G-guys have recently added support for playlists, but what are those good for, if users can't play those in the background (app stops MediaPlayer in onPause) while sending e-mails or browsing web pages?
 
+Jonatan Schroeder Apps don't need to compete for speaker access - internal media mixer service (something like SoundPool class) should be used for gathering all app sound data and playing it in the same timeline. It may sound a little bit like cacophony, but it allows for simple sound queuing and solves resource expropriation matter completely.
 
Audioid also wants to be a good citizen! Next update will ship the audio focus; and why not a setting to (in rare cases) disable this feature.
 
+Marcel Wesołowski YouTube is for video so, while it might be nice to be able to play just the sound in the background, it isn't that crazy that it isn't possible. Playlists are good for watching related videos.
 
+Marcel Wesołowski: I like that my podcast app stops playing when I get a notification or navigation instruction. At least give me the option to turn this on or off.
Also the YouTube app is a video player. If you can't see the video why keep playing? Granted there are times I wish it would but for the most part they are few.
 
Hi, we got a big problem. It seems that some other application (other music players, or in general unknown application) are requesting in a random way the audio focus, so android is sending us a AUDIOFOCUS_LOSS that is stopping our player while it's still playing music (without user interaction). 

Is there a way to avoid this cases?
 
+Emanuele Ricci Uninstall the misbehaving app and contact the developers to ask them to sort it out. Your app won't be the only app affected by this.
 
Told you that this is a crapy solution for audio resource expropiration :). All of this should be done (if it really has to) by OS layer instead of app requests.
 
+Marcel Wesołowski I can't share you view, and more importantly your tone.

One thing that I love about Android is how I can use the phone to play music with my favorite player and, at the same time, have the navigator app running. 

I don't usually have voice navigation activated but I do like to get voice messages when I'm near a radar, police control or stuff like that.

I love that the music fades a little to allow for a clear voice warning from the navigator. then the music volume goes back to it's level...

This kind of "kind" behaviour (or the lack of it)  is a reason enough for me to select a program to use for a specific purpose...

And in my opinión, you direct, drastic and strong opinion can be expressed in several better ways...
 
+Marcel Wesołowski, You maintain this is a OS level issue, but this API provides a way to let the OS know what kind of app you are.

You are the only one that knows the purpose of your app and you can make it behave "as well as possible" with out having the OS forcing you some way.

If you are a music app and want to fade when asked, you can.
If you want to pause, you can.
If you want to keep on going, you can...

On the other side, if you are a notifier app you can let everybody know when you do and decide what they want to do about it...

This only adds options (all of them), I don't get why you get so against it. Maybe it was the order to behave at the beginning that pissed you off.

Get over it man... but again you probably like screaming at movies and presentations ;) (get the joking tone man)
 
This kind of logic is necessary for AUDIO RECORDING focus. My app uses microphone in background and i want to provide access to mic for other apps if they need (voice input and others). How can i listen for other apps requesting microphone? 
Add a comment...