I am working on a music player which runs music as an Audio Service in the background.
Let's say that the music is playing through my app in background and user plays another media file from other app (Eg: Youtube) and then quits that app. That this pauses the music playing through my app and now the user has to resume the music manually.
How to auto resume the music file after an external media file closes?
I think you are looking for controlling the Audio Focus. This discusses how to implement the changes when another app / your app takes control of the audio focus, i.e. gain adjustments (ducking the volume).
mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
mPlaybackAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(mPlaybackAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(mMyFocusListener, mMyHandler)
.build();
mMediaPlayer = new MediaPlayer();
final Object mFocusLock = new Object();
boolean mPlaybackDelayed = false;
boolean mPlaybackNowAuthorized = false;
// ...
int res = mAudioManager.requestAudioFocus(mFocusRequest);
synchronized(mFocusLock) {
if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
mPlaybackNowAuthorized = false;
} else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mPlaybackNowAuthorized = true;
playbackNow();
} else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
mPlaybackDelayed = true;
mPlaybackNowAuthorized = false;
}
}
// ...
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
if (mPlaybackDelayed || mResumeOnFocusGain) {
synchronized(mFocusLock) {
mPlaybackDelayed = false;
mResumeOnFocusGain = false;
}
playbackNow();
}
break;
case AudioManager.AUDIOFOCUS_LOSS:
synchronized(mFocusLock) {
mResumeOnFocusGain = false;
mPlaybackDelayed = false;
}
pausePlayback();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
synchronized(mFocusLock) {
mResumeOnFocusGain = true;
mPlaybackDelayed = false;
}
pausePlayback();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// ... pausing or ducking depends on your app
break;
}
}
}
However please note as stated in the documentation :
Permanent loss of focus
If the audio focus loss is permanent (AUDIOFOCUS_LOSS), another app is playing audio. Your app should pause playback immediately, as it won't ever receive an AUDIOFOCUS_GAIN callback. To restart playback, the user must take an explicit action, like pressing the play transport control in a notification or app UI.
This is assuming that the permanent audio focus loss is received, however I can see some work arounds like polling for the audio focus, but probably best not to do that. As said, they have explicitly stated that:
the user must take an explicit action