8

I can't seem to find anything related to finding out what application got audio focus. I can correctly determine from my application what type of focus change it was, but not from any other application. Is there any way to determine what application received focus?

"What am I wanting to do?"

I have managed to record internal sound whether it be music or voice. If I am currently recording audio no matter the source, I want to determine what application took the focus over to determine what my application need's to do next.

Currently I am using the AudioManager.OnAudioFocusChangeListener for my application to stop recording internal sounds once the focus changes, but I want the application's name that gained the focus.

Trevor
  • 7,777
  • 6
  • 31
  • 50
  • just thinking loudly... how about getting the top of the currently running tasks? surely the app which just got audio focus must be ranking quite high up there. – alvi Jul 26 '15 at 18:44
  • 2
    FYI getRecentTasks() has been severely restricted in Android L. This feels like the wrong approach, i.e. something Android doesn't want to expose to applications, probably for security reasons. Perhaps there's a better approach, what would you do if you did find out the application name? – Trevor Carothers Jul 27 '15 at 02:07

3 Answers3

5

Short Answer: There's no good solution... and Android probably intended it this way.

Explanation: Looking at the source code, AudioManager has no API's(even hidden APIs) for checking who has Audio Focus. AudioManager wraps calls to AudioService which holds onto the real audio state. The API that AudioService exposes through it's Stub when AudioManager binds to it also does not have an API for querying current Audio Focus. Thus, even through reflection / system level permissions you won't be able get the information you want.

If you're curious how the focus changes are kept track of, you can look at MediaFocusControl whose instance is a member variable of AudioService here.

Untested Hacky Heuristic: You might be able to get some useful information by looking at UsageStats timestamps. Then once you have apps that were used within say ~500ms of you losing AudioFocus you can cross-check them against apps with Audio Permissions. You can follow this post to get permissions for any installed app.

This is clearly a heuristic and could require some tuning. It also requires the user to grant your app permissions to get access to the usage stats. Mileage may vary.

Community
  • 1
  • 1
Trevor Carothers
  • 2,250
  • 11
  • 19
  • If you target only lollipop he might be able to intercept the media notification and get the package that way. – JohanShogun Jul 27 '15 at 05:35
  • Thanks for the information it was all useful indeed. I was really busy with work and a few other thing's to get back to this thread. The `MediaFocusControl` was something I have dug into before, but had to go back to it to refresh my mind. I looked into the `UsageStats` and with what @JohanShogun suggested I have a working solution that seem's to be working good so far. Again, thank you for your help I appreciate it! – Trevor Aug 01 '15 at 03:41
  • Awesome, I've never actually used the UsageStats, glad they have a practical use – Trevor Carothers Aug 01 '15 at 04:50
  • I think is is impossible to guery stats when user controls playback only via notification – Vlad Sep 24 '20 at 09:04
3

Looking at the MediaContorller class (new in lollipop, available in comparability library for older versions).

There are these two methods that look interesting:

https://developer.android.com/reference/android/media/session/MediaController.html#getPackageName()

https://developer.android.com/reference/android/media/session/MediaController.html#getSessionActivity()

getPackageName supposedly returns the current sessions package name: http://androidxref.com/5.1.1_r6/xref/frameworks/base/media/java/android/media/session/MediaController.java#397

getSessionActivity gives you a PendingIntent with an activity to start (if one is supplied), where you could get the package as well.

Used together with your audio listener and a broadcast receiver for phone state to detect if the phone is currently ringing you might be able to use this in order to get a more fine grained detection than you currently have. As Trevor Carothers pointed out above, there is no way to get the general app with audio focus.

JohanShogun
  • 2,956
  • 21
  • 30
  • I found your post quite interesting which brought `MediaController` to mind which indeed is something I could work with. I used the `UsageStats` (@Trevor Carothers solution) along with `MediaController` to come to a solution that seem's to be working just fine as of now. Again, thank you I appreciate your help and time! – Trevor Aug 01 '15 at 03:45
  • `MediaController` only shows my app's package name and activity – Vlad Sep 24 '20 at 08:30
  • Okay, i have done it via using `NotificationListenerService` and reading extras of notifications in method `onNotificationPosted(notification: StatusBarNotification)`. But `getPackageName` is useless and `getSessionActivity` is always `null` for me – Vlad Sep 24 '20 at 09:01
2

You can use dumpsys audio to find who are using audio focus. And, you can also look into the results of dumpsys media_session.

And, if you want to find who're playing music, you can choose dumpsys media.audio_flinger. For myself, I switch to this command.

liudongmiao
  • 455
  • 4
  • 7