diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4d83092a..cfbb8aee 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -13,9 +13,8 @@
(Paused)
Click to start the music service.
- Headset only
- Audio only plays when a headset is plugged in
- Audio may play without a headset plugged in
+ Disallow Use of Speaker
+ Do not play music when the speaker would be used
Use Remote Player
Clicking the notification will open a mini-player dialog
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index b96adbcd..533e2eb2 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -6,8 +6,7 @@
android:key="headset_only"
android:title="@string/headset_only_title"
android:defaultValue="false"
- android:summaryOn="@string/headset_only_summary_on"
- android:summaryOff="@string/headset_only_summary_off" />
+ android:summary="@string/headset_only_summary" />
mWatchers;
- private NotificationManager mNotificationManager;
- private Method mStartForeground;
- private Method mStopForeground;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public Song[] getCurrentSongs()
@@ -150,15 +147,6 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
@Override
public void onCreate()
{
- mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- try {
- mStartForeground = getClass().getMethod("startForeground", new Class[] { int.class, Notification.class });
- mStopForeground = getClass().getMethod("stopForeground", new Class[] { boolean.class });
- } catch (NoSuchMethodException e) {
- // Running on an older platform.
- mStartForeground = mStopForeground = null;
- }
-
mWatchers = new RemoteCallbackList();
new Thread(this).start();
@@ -203,13 +191,12 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
setForeground(true);
mNotificationManager.notify(id, notification);
} else {
- Object[] startForegroundArgs = { Integer.valueOf(id), notification };
try {
- mStartForeground.invoke(this, startForegroundArgs);
+ mStartForeground.invoke(this, Integer.valueOf(id), notification);
} catch (InvocationTargetException e) {
- Log.w("VanillaMusic", "Unable to invoke startForeground", e);
+ Log.w("VanillaMusic", e);
} catch (IllegalAccessException e) {
- Log.w("VanillaMusic", "Unable to invoke startForeground", e);
+ Log.w("VanillaMusic", e);
}
}
}
@@ -219,13 +206,12 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
if (mStopForeground == null) {
setForeground(false);
} else {
- Object[] topForegroundArgs = { Boolean.FALSE };
try {
- mStopForeground.invoke(this, topForegroundArgs);
+ mStopForeground.invoke(this, Boolean.FALSE);
} catch (InvocationTargetException e) {
- Log.w("VanillaMusic", "Unable to invoke stopForeground", e);
+ Log.w("VanillaMusic", e);
} catch (IllegalAccessException e) {
- Log.w("VanillaMusic", "Unable to invoke stopForeground", e);
+ Log.w("VanillaMusic", e);
}
}
}
@@ -304,6 +290,8 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
private PowerManager.WakeLock mWakeLock;
private Notification mNotification;
private SharedPreferences mSettings;
+ private AudioManager mAudioManager;
+ private NotificationManager mNotificationManager;
private int[] mSongs;
private ArrayList mSongTimeline;
@@ -313,6 +301,12 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
private int mState = STATE_NORMAL;
private boolean mPlayingBeforeCall;
+ private Method mIsWiredHeadsetOn;
+ private Method mIsBluetoothScoOn;
+ private Method mIsBluetoothA2dpOn;
+ private Method mStartForeground;
+ private Method mStopForeground;
+
private static final int SET_SONG = 0;
private static final int PLAY_PAUSE = 1;
private static final int HEADSET_PLUGGED = 2;
@@ -433,6 +427,23 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(mCallListener, PhoneStateListener.LISTEN_CALL_STATE);
+ mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
+ try {
+ mIsWiredHeadsetOn = mAudioManager.getClass().getMethod("isWiredHeadsetOn", (Class[]) null);
+ mIsBluetoothScoOn = mAudioManager.getClass().getMethod("isBluetoothScoOn", (Class[]) null);
+ mIsBluetoothA2dpOn = mAudioManager.getClass().getMethod("isBluetoothA2dpOn", (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ Log.d("VanillaMusic", "falling back to pre-2.0 AudioManager APIs");
+ }
+
+ mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+ try {
+ mStartForeground = getClass().getMethod("startForeground", int.class, Notification.class);
+ mStopForeground = getClass().getMethod("stopForeground", boolean.class);
+ } catch (NoSuchMethodException e) {
+ Log.d("VanillaMusic", "falling back to pre-2.0 Service APIs");
+ }
+
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnCompletionListener(this);
@@ -455,7 +466,7 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
{
if ("headset_only".equals(key)) {
mHeadsetOnly = mSettings.getBoolean(key, false);
- if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
+ if (mHeadsetOnly && isSpeakerOn() && mMediaPlayer.isPlaying())
pause();
} else if ("remote_player".equals(key)) {
mUseRemotePlayer = mSettings.getBoolean(key, true);
@@ -536,9 +547,25 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
+ private boolean isSpeakerOn()
+ {
+ try {
+ return !(Boolean)mIsWiredHeadsetOn.invoke(mAudioManager, (Object[])null)
+ && !(Boolean)mIsBluetoothScoOn.invoke(mAudioManager, (Object[])null)
+ && !(Boolean)mIsBluetoothA2dpOn.invoke(mAudioManager, (Object[])null);
+ } catch (InvocationTargetException e) {
+ Log.w("VanillaMusic", e);
+ } catch (IllegalAccessException e) {
+ Log.w("VanillaMusic", e);
+ }
+
+ // Why is there no true equivalent to this in Android 2.0?
+ return (mAudioManager.getRouting(mAudioManager.getMode()) & AudioManager.ROUTE_SPEAKER) != 0;
+ }
+
private void play()
{
- if (mHeadsetOnly && !mPlugged)
+ if (mHeadsetOnly && isSpeakerOn())
return;
mMediaPlayer.start();