Abandon audio focus when a phone call comes in

Otherwise playback continues directly after the end of the call
This commit is contained in:
daniel oeh 2014-08-01 13:17:02 +02:00
parent 876b69d21c
commit 18372a4d9b

View File

@ -4,12 +4,21 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.RemoteControlClient; import android.media.RemoteControlClient;
import android.telephony.TelephonyManager;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import de.danoeh.antennapod.BuildConfig; import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.feed.Chapter; import de.danoeh.antennapod.feed.Chapter;
import de.danoeh.antennapod.feed.MediaType; import de.danoeh.antennapod.feed.MediaType;
@ -20,14 +29,6 @@ import de.danoeh.antennapod.util.playback.IPlayer;
import de.danoeh.antennapod.util.playback.Playable; import de.danoeh.antennapod.util.playback.Playable;
import de.danoeh.antennapod.util.playback.VideoPlayer; import de.danoeh.antennapod.util.playback.VideoPlayer;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* Manages the MediaPlayer object of the PlaybackService. * Manages the MediaPlayer object of the PlaybackService.
*/ */
@ -380,7 +381,8 @@ public class PlaybackServiceMediaPlayer {
} else if (mediaPlayer != null) { } else if (mediaPlayer != null) {
mediaPlayer.reset(); mediaPlayer.reset();
} else { } else {
if (BuildConfig.DEBUG) Log.d(TAG, "Call to reinit was ignored: media and mediaPlayer were null"); if (BuildConfig.DEBUG)
Log.d(TAG, "Call to reinit was ignored: media and mediaPlayer were null");
} }
playerLock.unlock(); playerLock.unlock();
} }
@ -694,54 +696,56 @@ public class PlaybackServiceMediaPlayer {
public void run() { public void run() {
playerLock.lock(); playerLock.lock();
switch (focusChange) { // If there is an incoming call, playback should be paused permanently
case AudioManager.AUDIOFOCUS_LOSS: TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (BuildConfig.DEBUG) final int callState = (tm != null) ? tm.getCallState() : 0;
Log.d(TAG, "Lost audio focus"); if (BuildConfig.DEBUG) Log.d(TAG, "Call state: " + callState);
pause(true, false); Log.i(TAG, "Call state:" + callState);
callback.shouldStop();
break; if (focusChange == AudioManager.AUDIOFOCUS_LOSS || callState != TelephonyManager.CALL_STATE_IDLE) {
case AudioManager.AUDIOFOCUS_GAIN: if (BuildConfig.DEBUG)
if (BuildConfig.DEBUG) Log.d(TAG, "Lost audio focus");
Log.d(TAG, "Gained audio focus"); pause(true, false);
if (pausedBecauseOfTransientAudiofocusLoss) // we paused => play now callback.shouldStop();
resume(); } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
else // we ducked => raise audio level back if (BuildConfig.DEBUG)
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, Log.d(TAG, "Gained audio focus");
AudioManager.ADJUST_RAISE, 0); if (pausedBecauseOfTransientAudiofocusLoss) { // we paused => play now
break; resume();
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: } else { // we ducked => raise audio level back
if (playerStatus == PlayerStatus.PLAYING) { audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
if (!UserPreferences.shouldPauseForFocusLoss()) { AudioManager.ADJUST_RAISE, 0);
if (BuildConfig.DEBUG) }
Log.d(TAG, "Lost audio focus temporarily. Ducking..."); } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, if (playerStatus == PlayerStatus.PLAYING) {
AudioManager.ADJUST_LOWER, 0); if (!UserPreferences.shouldPauseForFocusLoss()) {
pausedBecauseOfTransientAudiofocusLoss = false;
} else {
if (BuildConfig.DEBUG)
Log.d(TAG, "Lost audio focus temporarily. Could duck, but won't, pausing...");
pause(false, false);
pausedBecauseOfTransientAudiofocusLoss = true;
}
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
if (playerStatus == PlayerStatus.PLAYING) {
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
Log.d(TAG, "Lost audio focus temporarily. Pausing..."); Log.d(TAG, "Lost audio focus temporarily. Ducking...");
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, 0);
pausedBecauseOfTransientAudiofocusLoss = false;
} else {
if (BuildConfig.DEBUG)
Log.d(TAG, "Lost audio focus temporarily. Could duck, but won't, pausing...");
pause(false, false); pause(false, false);
pausedBecauseOfTransientAudiofocusLoss = true; pausedBecauseOfTransientAudiofocusLoss = true;
} }
}
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
if (playerStatus == PlayerStatus.PLAYING) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Lost audio focus temporarily. Pausing...");
pause(false, false);
pausedBecauseOfTransientAudiofocusLoss = true;
}
playerLock.unlock();
} }
playerLock.unlock();
} }
}); });
} }
}; };
public void endPlayback() { public void endPlayback() {
executor.submit(new Runnable() { executor.submit(new Runnable() {
@Override @Override
@ -778,7 +782,8 @@ public class PlaybackServiceMediaPlayer {
if (playerStatus == PlayerStatus.INDETERMINATE) { if (playerStatus == PlayerStatus.INDETERMINATE) {
setPlayerStatus(PlayerStatus.STOPPED, null); setPlayerStatus(PlayerStatus.STOPPED, null);
} else { } else {
if (BuildConfig.DEBUG) Log.d(TAG, "Ignored call to stop: Current player state is: " + playerStatus); if (BuildConfig.DEBUG)
Log.d(TAG, "Ignored call to stop: Current player state is: " + playerStatus);
} }
playerLock.unlock(); playerLock.unlock();