Audio focus
This commit is contained in:
parent
95b5965a12
commit
61a12c6140
@ -30,19 +30,58 @@ import android.media.AudioManager;
|
|||||||
/**
|
/**
|
||||||
* Framework methods only in Froyo or above go here.
|
* Framework methods only in Froyo or above go here.
|
||||||
*/
|
*/
|
||||||
public class CompatFroyo {
|
public class CompatFroyo implements AudioManager.OnAudioFocusChangeListener {
|
||||||
|
/**
|
||||||
|
* Instance of the audio focus listener created by {@link #createAudioFocus()}.
|
||||||
|
*/
|
||||||
|
private static CompatFroyo sAudioFocus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}.
|
||||||
|
*/
|
||||||
public static void registerMediaButtonEventReceiver(AudioManager manager, ComponentName receiver)
|
public static void registerMediaButtonEventReceiver(AudioManager manager, ComponentName receiver)
|
||||||
{
|
{
|
||||||
manager.registerMediaButtonEventReceiver(receiver);
|
manager.registerMediaButtonEventReceiver(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link AudioManager#unregisterMediaButtonEventReceiver(ComponentName)}.
|
||||||
|
*/
|
||||||
public static void unregisterMediaButtonEventReceiver(AudioManager manager, ComponentName receiver)
|
public static void unregisterMediaButtonEventReceiver(AudioManager manager, ComponentName receiver)
|
||||||
{
|
{
|
||||||
manager.unregisterMediaButtonEventReceiver(receiver);
|
manager.unregisterMediaButtonEventReceiver(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link BackupManager#dataChanged()}.
|
||||||
|
*/
|
||||||
public static void dataChanged(Context context)
|
public static void dataChanged(Context context)
|
||||||
{
|
{
|
||||||
new BackupManager(context).dataChanged();
|
new BackupManager(context).dataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an audio focus listener that calls back to {@link PlaybackService#onAudioFocusChange(int)}.
|
||||||
|
*/
|
||||||
|
public static void createAudioFocus()
|
||||||
|
{
|
||||||
|
sAudioFocus = new CompatFroyo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int)}
|
||||||
|
*/
|
||||||
|
public static void requestAudioFocus(AudioManager manager)
|
||||||
|
{
|
||||||
|
manager.requestAudioFocus(sAudioFocus, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioFocusChange(int type)
|
||||||
|
{
|
||||||
|
PlaybackService service = PlaybackService.sInstance;
|
||||||
|
if (service != null) {
|
||||||
|
service.onAudioFocusChange(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,11 @@ public final class PlaybackService extends Service
|
|||||||
*/
|
*/
|
||||||
private static final long IDLE_GRACE_PERIOD = 60000;
|
private static final long IDLE_GRACE_PERIOD = 60000;
|
||||||
|
|
||||||
private static final Object sWait = new Object();
|
private static final Object sWait = new Object[0];
|
||||||
private static PlaybackService sInstance;
|
/**
|
||||||
|
* The appplication-wide instance of the PlaybackService.
|
||||||
|
*/
|
||||||
|
public static PlaybackService sInstance;
|
||||||
private static final ArrayList<PlaybackActivity> sActivities = new ArrayList<PlaybackActivity>(5);
|
private static final ArrayList<PlaybackActivity> sActivities = new ArrayList<PlaybackActivity>(5);
|
||||||
/**
|
/**
|
||||||
* Cached app-wide SharedPreferences instance.
|
* Cached app-wide SharedPreferences instance.
|
||||||
@ -300,6 +303,10 @@ public final class PlaybackService extends Service
|
|||||||
* indicates that no timeout has occurred.
|
* indicates that no timeout has occurred.
|
||||||
*/
|
*/
|
||||||
private long mIdleStart = -1;
|
private long mIdleStart = -1;
|
||||||
|
/**
|
||||||
|
* True if the last audio focus loss can be ducked.
|
||||||
|
*/
|
||||||
|
private boolean mDuckedLoss;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate()
|
public void onCreate()
|
||||||
@ -319,6 +326,10 @@ public final class PlaybackService extends Service
|
|||||||
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||||
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
|
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
|
||||||
|
CompatFroyo.createAudioFocus();
|
||||||
|
}
|
||||||
|
|
||||||
SharedPreferences settings = getSettings(this);
|
SharedPreferences settings = getSettings(this);
|
||||||
settings.registerOnSharedPreferenceChangeListener(this);
|
settings.registerOnSharedPreferenceChangeListener(this);
|
||||||
mNotificationMode = Integer.parseInt(settings.getString("notification_mode", "1"));
|
mNotificationMode = Integer.parseInt(settings.getString("notification_mode", "1"));
|
||||||
@ -335,13 +346,26 @@ public final class PlaybackService extends Service
|
|||||||
mHeadsetPlay = settings.getBoolean("headset_play", false);
|
mHeadsetPlay = settings.getBoolean("headset_play", false);
|
||||||
mInvertNotification = settings.getBoolean("notification_inverted_color", false);
|
mInvertNotification = settings.getBoolean("notification_inverted_color", false);
|
||||||
mNotificationAction = createNotificationAction(settings);
|
mNotificationAction = createNotificationAction(settings);
|
||||||
|
mHeadsetPause = getSettings(this).getBoolean("headset_pause", true);
|
||||||
|
|
||||||
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
|
PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
|
||||||
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VanillaMusicLock");
|
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VanillaMusicLock");
|
||||||
|
|
||||||
|
mCallListener = new InCallListener();
|
||||||
|
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
telephonyManager.listen(mCallListener, PhoneStateListener.LISTEN_CALL_STATE);
|
||||||
|
|
||||||
|
mReceiver = new Receiver();
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
||||||
|
filter.addAction(Intent.ACTION_HEADSET_PLUG);
|
||||||
|
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||||
|
registerReceiver(mReceiver, filter);
|
||||||
|
|
||||||
|
getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mObserver);
|
||||||
|
|
||||||
mLooper = thread.getLooper();
|
mLooper = thread.getLooper();
|
||||||
mHandler = new Handler(mLooper, this);
|
mHandler = new Handler(mLooper, this);
|
||||||
mHandler.sendEmptyMessage(POST_CREATE);
|
|
||||||
|
|
||||||
initWidgets();
|
initWidgets();
|
||||||
|
|
||||||
@ -556,6 +580,9 @@ public final class PlaybackService extends Service
|
|||||||
if (mNotificationMode != NEVER)
|
if (mNotificationMode != NEVER)
|
||||||
startForeground(NOTIFICATION_ID, createNotification(mCurrentSong, mState));
|
startForeground(NOTIFICATION_ID, createNotification(mCurrentSong, mState));
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
|
||||||
|
CompatFroyo.requestAudioFocus(mAudioManager);
|
||||||
|
}
|
||||||
if (mWakeLock != null)
|
if (mWakeLock != null)
|
||||||
mWakeLock.acquire();
|
mWakeLock.acquire();
|
||||||
} else {
|
} else {
|
||||||
@ -968,18 +995,6 @@ public final class PlaybackService extends Service
|
|||||||
loadPreference(key);
|
loadPreference(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupReceiver()
|
|
||||||
{
|
|
||||||
if (mReceiver == null)
|
|
||||||
mReceiver = new Receiver();
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
|
||||||
filter.addAction(Intent.ACTION_HEADSET_PLUG);
|
|
||||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
|
||||||
registerReceiver(mReceiver, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int POST_CREATE = 1;
|
|
||||||
/**
|
/**
|
||||||
* Run the given query and add the results to the timeline.
|
* Run the given query and add the results to the timeline.
|
||||||
*
|
*
|
||||||
@ -1030,16 +1045,6 @@ public final class PlaybackService extends Service
|
|||||||
case QUERY:
|
case QUERY:
|
||||||
runQuery(message.arg1, (QueryTask)message.obj, message.arg2);
|
runQuery(message.arg1, (QueryTask)message.obj, message.arg2);
|
||||||
break;
|
break;
|
||||||
case POST_CREATE:
|
|
||||||
mHeadsetPause = getSettings(this).getBoolean("headset_pause", true);
|
|
||||||
setupReceiver();
|
|
||||||
|
|
||||||
mCallListener = new InCallListener();
|
|
||||||
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
|
||||||
telephonyManager.listen(mCallListener, PhoneStateListener.LISTEN_CALL_STATE);
|
|
||||||
|
|
||||||
getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mObserver);
|
|
||||||
break;
|
|
||||||
case IDLE_TIMEOUT:
|
case IDLE_TIMEOUT:
|
||||||
if ((mState & FLAG_PLAYING) != 0)
|
if ((mState & FLAG_PLAYING) != 0)
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(FADE_OUT, 100, 0));
|
mHandler.sendMessage(mHandler.obtainMessage(FADE_OUT, 100, 0));
|
||||||
@ -1511,4 +1516,26 @@ public final class PlaybackService extends Service
|
|||||||
notification.contentIntent = mNotificationAction;
|
notification.contentIntent = mNotificationAction;
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onAudioFocusChange(int type)
|
||||||
|
{
|
||||||
|
Log.d("VanillaMusic", "audio focus change: " + type);
|
||||||
|
switch (type) {
|
||||||
|
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
|
||||||
|
mDuckedLoss = (mState & FLAG_PLAYING) != 0;
|
||||||
|
unsetFlag(FLAG_PLAYING);
|
||||||
|
break;
|
||||||
|
case AudioManager.AUDIOFOCUS_LOSS:
|
||||||
|
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||||
|
mDuckedLoss = false;
|
||||||
|
unsetFlag(FLAG_PLAYING);
|
||||||
|
break;
|
||||||
|
case AudioManager.AUDIOFOCUS_GAIN:
|
||||||
|
if (mDuckedLoss) {
|
||||||
|
mDuckedLoss = false;
|
||||||
|
setFlag(FLAG_PLAYING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user