Interrupting MediaPlayer - android

My application makes a short announcement once in a while, either via TextToSpeech or using the MediaPlayer. If there is some other music running in the background probably by some application using the MediaPlayer, I would like to interrupt this music for a moment and after my announcement resume playing the "background music".
Is there a way to do it?

If you can target API level 8 and above (Android 2.2), then have a look into the AudioManager, specifically requestAudioFocus() with AUDIOFOCUS_GAIN_TRANSIENT and AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, and abandonAudioFocus().
These give hints to the currently-playing music stream that your app would like to play a brief sound. If you use AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK with requestAudioFocus() you can get a nice effect where the already-playing music pauses, your sound plays, and then the playing music fades back in again when you call abandonAudioFocus().
This works nicely with the built-in media players on the 2.2 devices I've tried it with (Samsung Galaxy S Wi-Fi and HTC Wildfire.) I've not tried it extensively with other music-playing apps, but it definitely works with Spotify, at least, and is the official way of doing exactly what you want to do.
Note that you'll need to work out for yourself when to call abandonAudioFocus() as most sounds are played asynchronously. Luckily, both MediaPlayer and TextToSpeech provide callback mechanisms so they can give you a prod when they've finished playing your sound (this isn't true of SoundPool, so that's more annoying to use audio focus with.)

I don't think there is a standard way to do it for every music player out there. At least for the Android music player you could do:
Intent i;
i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
context.sendBroadcast(i);
Another way to do it would be to set the stream volume for type "music" to 0, and play your announcement on another stream type.

Related

How to check if external media player is playing in android?

I want to stop my media player if external media player is playing.
I've implemented following code but it is called even when my app media player is playing.
if (audioManager.isMusicActive()) {
return;
}
How to distinguish between in-app media player and external media player?
Any help would be appreciated.
Two or more Android apps can play audio to the same output stream
simultaneously. The system mixes everything together. While this is
technically impressive, it can be very aggravating to a user. To avoid
every music app playing at the same time, Android introduces the idea
of audio focus. Only one app can hold audio focus at a time.
Further,
A well-behaved audio app should manage audio focus according to these
general guidelines:
Call requestAudioFocus() immediately before starting to play and
verify that the call returns AUDIOFOCUS_REQUEST_GRANTED. If you design
your app as we describe in this guide, the call to requestAudioFocus()
should be made in the onPlay() callback of your media session. When
another app gains audio focus, stop or pause playing, or duck the
volume down. When playback stops, abandon audio focus. Audio focus is
handled differently depending on the the version of Android that is
running:
You can check the more detail from developer link.

Abandoning audio focus does not resume music streaming for other apps

I'm working on an app allowing users to watch videos. When they open a video to watch, I call:
AudioManager mAudioManager = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
This stops playback from any other apps streaming music at the time. I've tested with Play Music, Spotify, Soundcloud, etc and they all stop music playback at this point.
When the user is done watching a video, I call
mAudioManager.abandonAudioFocus(this);
but the app that was streaming music and previously paused does not resume streaming music. How can I get this to work?
I've tried doing AUDIOFOCUS_GAIN and AUDIOFOCUS_GAIN_TRANSIENT. Everything I've read on Stack Overflow just says I just need to release the audio manager. This seems so simple, but I can't figure it out. I want the functionality to be similar to how Instagram pauses and resumes music when you view a video.
As you are requesting the complete 'AUDIO_FOCUS', the external application has to hit the play button to request the 'AUDIO_FOCUS' back. Just because your application has gained the 'AUDIO_FOCUS' and then abandoned it, this wouldn't resume the previous music/video which was being played.
The only way to overcome this would be to rethink the requirement of the application. Therefore, you can request temporary audio focus, i.e. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT (or AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_CAN_DUCK depending on whether or not you think it's ok for other audio to keep playing in the background at a lower volume).
int requestAudioFocusResult = audioManager.requestAudioFocus(TimeWhisperService.this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
if(requestAudioFocusResult == AudioManager.AUDIOFOCUS_GAIN) {
//ACCESS GRANTED
}

Pause/Stop/Mute music at service interupts

I basically have an audio application that will be playing some music. I want to be able to pause/stop/mute the music when there is an interrupt.
These interrupts include: GPS directions, Phone Call, GPS, etc. (if there are more audio interupts, please let me know)
I already implemented the phone call interrupt, stops the music when phone call received and plays after phone call ends.
How would I do the other interrupts?
EDIT:
I noticed that Android's Play Music application does this. But I am unable to find the source code of that, not sure if that would be helpful.
Make sure you correctly ask for and release Audio Focus as described here:
http://developer.android.com/training/managing-audio/audio-focus.html
With multiple apps potentially playing audio it's important to think about how they should interact. To avoid every music app playing at the same time, Android uses audio focus to moderate audio playback—only apps that hold the audio focus should play audio.
Basically this allows the framework to handle interrupts properly as you cannot specifically code for every situation.

Android Play Sound even if Media Volume is 0

I want to play music with AudioTrack even if the media volume of the device is 0.
In my app, I want to have a SeekBar for the media volume (maybe if other music runs in the background) and one other SeekBar for the music of my app.
Until now, I can change the media volume. But then the music of my app is also silent..
How can I do that?
I think there is Six Different Streams of Sound in Android for Playing Different Types of Sounds
The first step to creating a predictable audio experience is understanding which audio stream your app will use.
Android maintains a separate audio stream for playing
music,
alarms,
notifications,
the incoming call ringer,
system sounds,
in-call volume,
and DTMF tones.
This is done primarily to allow users to control the volume of each stream independently.
Use Hardware Volume Keys to Control Your App’s Audio Volume
By default, pressing the volume controls modify the volume of the active audio stream. If your app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.
If you've got a game or music app, then chances are good that when the user hits the volume keys they want to control the volume of the game or music, even if they’re currently between songs or there’s no music in the current game location.
You may be tempted to try and listen for volume key presses and modify the volume of your audio stream that way. Resist the urge. Android provides the handy setVolumeControlStream() method to direct volume key presses to the audio stream you specify.
Having identified the audio stream your application will be using, you should set it as the volume stream target. You should make this call early in your app’s lifecycle—because you only need to call it once during the activity lifecycle, you should typically call it within the onCreate() method (of the Activity or Fragment that controls your media). This ensures that whenever your app is visible, the volume controls function as the user expects.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
From this point onwards, pressing the volume keys on the device affect the audio stream you specify (in this case “music”) whenever the target activity or fragment is visible.
Thanks for your answers.
Now I use "AudioTrack(AudioManager.STREAM_SYSTEM, (...))" and it's working good.
Maybe it's not the best method but by now, it's working.

Is it possible to control the volume of the default media player in Android from an Android application

I have the following requirement.
I am developing an Android mobile application. A timer has been set for a specific duration for an activity.
I need to play "beep" sound three times when the timer duration is 10 seconds left to complete (i.e. become zero), two times "beep" sound when the timer duration is 5 seconds left to complete & once "beep" sound when the timer completes.
The user may be playing music using the default music player of the Android phone while using the Android mobile application. I need to implement the logic so that when the "beep" sound is being played from the mobile application, I need to first decrease the volume of the default music & then play the "beep" sound & again reset to the original volume after the "beep" sound have been played the required no of times.
I wanted to know, whether this is technically feasible or not.
Yes, you can use AudioManager to change the volume for music. The function [setStreamVolume][2] is what you're looking for. The stream type you're looking for is AudioManager.STREAM_MUSIC
[2]: http://developer.android.com/reference/android/media/AudioManager.html#setStreamVolume(int, int, int)
One way to achieve this is by using the platform's ability to allow your app to request audio focus while allowing other apps to "duck". This allows you to tell the system .. "Hey, I'm going to play something, tell other apps also playing audio that it's ok to continue playing but to lower their volume".
Here is the relevant sample code and note from the Managing Audio Focus section.
When requesting transient audio focus you have an additional option:
whether or not you want to enable "ducking." Normally, when a
well-behaved audio app loses audio focus it immediately silences its
playback. By requesting a transient audio focus that allows ducking
you tell other audio apps that it’s acceptable for them to keep
playing, provided they lower their volume until the focus returns to
them.
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
int result = am.requestAudioFocus(afChangeListener,
// Use the music stream.
AudioManager.STREAM_NOTIFICATION,
//tell them it's ok to duck
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// Start playback.
}
I hope it helps someone.

Categories

Resources