Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Receive Broadcast on Audio Focus change

I am trying to write an app that detects whenever any app on the device starts or stops playing music. My app is not a media player, it's more of a dashboard functionality, so I have no need of requesting audio focus, but I want to know when other apps do so I can update my status text accordingly.

Essentially, I believe that the function AudioManager.isMusicActive() will provide essentially exactly what I want to know, however since I am writing a service that will be always on I would like to avoid needing to poll that on a constant basis. I need the information in near real time, so it would essentially be a 1 second poll in perpetuity.

I'm looking for a way to detect when STREAM_MUSIC is being used by another app.

Some ways I have thought about doing it:

(1) Again, a perpetual poll using either Timer or Handler to constantly poll the isMusicActive() function. Not ideal from a battery or processor management perspective. I could use a flag variable in the UI Activity to control when the poll runs (it isn't really necessary when the UI isn't in the foreground, anyways), but I still think I'm using more processor/battery time than I'd need to.

(2) Listen for a broadcast of some kind, but none of the Android audio broadcasts seem to really fit the bill. (that I could find)

(3) I could, I suppose, request audio focus and just never play any audio and never give it up. Theoretically, since I am starting this in an always on service I believe that should allow my app to sit at the bottom of the LIFO audio focus stack and I would be notified via the AudioManager.OnAudioFocusChangeListener mechanism in basically the opposite way of its intended purpose (i.e. turn on my app when I lose audio focus and turn it off when I gain audio focus back). However, I'm not entirely sure how doing something like this would function in real-life usage. I feel like abusing the audio focus methodology for something like this could very easily result in negative user experiences in situations I haven't even thought of.

(4) Is there a way to use the AudioManager.OnAudioFocusChangeListener (or similar) without needing to request audio focus at all?

Are there any other ways I could go about doing this? Just a pointer in the right direction would be incredibly helpful!

like image 618
QuotidianVoid Avatar asked Feb 11 '14 01:02

QuotidianVoid


1 Answers

I needed similar thing, so did a bit of research. Unfortunately, there seems to be no other way to accomplish this except of requesting audio focus in your app.

Material for study:

Check Android source code in frameworks\base\media\java\android\media\ where you can find actual code for requestAudioFocus in MediaFocusControl class.

Other classes in this folder show how they send broadcast events for volume change, bluetooth on/off, etc, but no broadcast event at all related to audio enabled/disabled.

Another information on topic:

  • http://developer.android.com/training/managing-audio/audio-focus.html
  • http://developer.android.com/training/managing-audio/audio-output.html

Other than that, there doesn't seem to be any documented way to know when audio hardware starts/stops to play.

I trust that requesting audio focus without actually playing audio should not consume any battery. Only one ugly side effect is that this stops currently played audio.

like image 53
Pointer Null Avatar answered Oct 11 '22 22:10

Pointer Null