Android - can I mute currently playing audio applications?

user235900 picture user235900 · Jan 3, 2010 · Viewed 21.6k times · Source

Hi I'm new to this. My self-teaching project is a small application which plays an audio news stream. To be effective, the application really needs to interrupt any currently playing media players (eg: Last FM, Imeem, music player, Spotify etc).

I don't know what will be playing or what application will be playing it, but I want to ask them all to pause until I've done. Sounds rather bold, I know, but it must be possible, because when there's an incoming call, that's basically what happens.

Can I send a message to all audio players asking them to pause for a moment? Could I spoof an incoming call, just for the time it takes?

Thanks.

Answer

Christopher Orr picture Christopher Orr · Jan 3, 2010

Audio handling on Android is going to be pretty horrible for a while. The APIs are pretty weird, poorly documented, and keep changing/deprecating/breaking between versions. Even the AudioManager code has FIXMEs in it.

Anyway, there are several stream types in Android (music, notifications, phone calls, etc.) and applications are meant to choose the appropriate one for playback. I imagine the majority of Android apps should use the music/media type (STREAM_TYPE_MUSIC). You set this on your MediaPlayer using the setAudioStreamType method.

The SDK does allow you to set a single stream type as solo — causing all other streams to be muted — but I don't believe you can identify the audio being played back by particular applications and somehow pause/unpause it. Music applications in general will use the PhoneStateListener to pause themselves when a call comes in.

So in your case, you could "borrow" the phone call stream for your MediaPlayer and use the method call AudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true) when playback begins, then un-solo the stream with false when playback or your Activity is done.

I can tell you that this works, but I can't remember offhand whether you need to also set the audio mode to MODE_IN_CALL when using the voice call stream (like this: AudioManager.setMode(AudioManager.MODE_IN_CALL)). If you find that is required, then you need to make sure you return the mode to MODE_NORMAL once playback completes, otherwise whenever you press the volume hard keys, it'll say "In-call volume"! However, if and when you do want to change back to MODE_NORMAL, you must check that a genuine phone call isn't happening at that time...

Maybe you could use another stream type rather than the voice call one, but I'm just speaking from experience working on an app that could use either the speakerphone or the earpiece for audio playback, which requires the use of the voice call stream.

Like I said, audio handling isn't particularly fun... ;)