Expand and improve headset detection
Modify it to mean play through anything but the internal speaker. Should now detect bluetooth and other sinks. I have not tested this on Android 2.0+. I hope it works...
This commit is contained in:
parent
a456aa8c04
commit
cddfb03627
@ -13,9 +13,8 @@
|
|||||||
<string name="paused">(Paused)</string>
|
<string name="paused">(Paused)</string>
|
||||||
<string name="widget_start_service">Click to start the music service.</string>
|
<string name="widget_start_service">Click to start the music service.</string>
|
||||||
|
|
||||||
<string name="headset_only_title">Headset only</string>
|
<string name="headset_only_title">Disallow Use of Speaker</string>
|
||||||
<string name="headset_only_summary_on">Audio only plays when a headset is plugged in</string>
|
<string name="headset_only_summary">Do not play music when the speaker would be used</string>
|
||||||
<string name="headset_only_summary_off">Audio may play without a headset plugged in</string>
|
|
||||||
|
|
||||||
<string name="remote_player_title">Use Remote Player</string>
|
<string name="remote_player_title">Use Remote Player</string>
|
||||||
<string name="remote_player_summary_on">Clicking the notification will open a mini-player dialog</string>
|
<string name="remote_player_summary_on">Clicking the notification will open a mini-player dialog</string>
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
android:key="headset_only"
|
android:key="headset_only"
|
||||||
android:title="@string/headset_only_title"
|
android:title="@string/headset_only_title"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:summaryOn="@string/headset_only_summary_on"
|
android:summary="@string/headset_only_summary" />
|
||||||
android:summaryOff="@string/headset_only_summary_off" />
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="remote_player"
|
android:key="remote_player"
|
||||||
android:title="@string/remote_player_title"
|
android:title="@string/remote_player_title"
|
||||||
|
@ -65,9 +65,6 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
public static final int STATE_PLAYING = 2;
|
public static final int STATE_PLAYING = 2;
|
||||||
|
|
||||||
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
|
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
|
||||||
private NotificationManager mNotificationManager;
|
|
||||||
private Method mStartForeground;
|
|
||||||
private Method mStopForeground;
|
|
||||||
|
|
||||||
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
|
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
|
||||||
public Song[] getCurrentSongs()
|
public Song[] getCurrentSongs()
|
||||||
@ -150,15 +147,6 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate()
|
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<IMusicPlayerWatcher>();
|
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
|
||||||
|
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
@ -203,13 +191,12 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
setForeground(true);
|
setForeground(true);
|
||||||
mNotificationManager.notify(id, notification);
|
mNotificationManager.notify(id, notification);
|
||||||
} else {
|
} else {
|
||||||
Object[] startForegroundArgs = { Integer.valueOf(id), notification };
|
|
||||||
try {
|
try {
|
||||||
mStartForeground.invoke(this, startForegroundArgs);
|
mStartForeground.invoke(this, Integer.valueOf(id), notification);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
Log.w("VanillaMusic", "Unable to invoke startForeground", e);
|
Log.w("VanillaMusic", e);
|
||||||
} catch (IllegalAccessException 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) {
|
if (mStopForeground == null) {
|
||||||
setForeground(false);
|
setForeground(false);
|
||||||
} else {
|
} else {
|
||||||
Object[] topForegroundArgs = { Boolean.FALSE };
|
|
||||||
try {
|
try {
|
||||||
mStopForeground.invoke(this, topForegroundArgs);
|
mStopForeground.invoke(this, Boolean.FALSE);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
Log.w("VanillaMusic", "Unable to invoke stopForeground", e);
|
Log.w("VanillaMusic", e);
|
||||||
} catch (IllegalAccessException 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 PowerManager.WakeLock mWakeLock;
|
||||||
private Notification mNotification;
|
private Notification mNotification;
|
||||||
private SharedPreferences mSettings;
|
private SharedPreferences mSettings;
|
||||||
|
private AudioManager mAudioManager;
|
||||||
|
private NotificationManager mNotificationManager;
|
||||||
|
|
||||||
private int[] mSongs;
|
private int[] mSongs;
|
||||||
private ArrayList<Song> mSongTimeline;
|
private ArrayList<Song> mSongTimeline;
|
||||||
@ -313,6 +301,12 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
private int mState = STATE_NORMAL;
|
private int mState = STATE_NORMAL;
|
||||||
private boolean mPlayingBeforeCall;
|
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 SET_SONG = 0;
|
||||||
private static final int PLAY_PAUSE = 1;
|
private static final int PLAY_PAUSE = 1;
|
||||||
private static final int HEADSET_PLUGGED = 2;
|
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 telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
telephonyManager.listen(mCallListener, PhoneStateListener.LISTEN_CALL_STATE);
|
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.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
mMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
|
mMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
|
||||||
mMediaPlayer.setOnCompletionListener(this);
|
mMediaPlayer.setOnCompletionListener(this);
|
||||||
@ -455,7 +466,7 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
{
|
{
|
||||||
if ("headset_only".equals(key)) {
|
if ("headset_only".equals(key)) {
|
||||||
mHeadsetOnly = mSettings.getBoolean(key, false);
|
mHeadsetOnly = mSettings.getBoolean(key, false);
|
||||||
if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
|
if (mHeadsetOnly && isSpeakerOn() && mMediaPlayer.isPlaying())
|
||||||
pause();
|
pause();
|
||||||
} else if ("remote_player".equals(key)) {
|
} else if ("remote_player".equals(key)) {
|
||||||
mUseRemotePlayer = mSettings.getBoolean(key, true);
|
mUseRemotePlayer = mSettings.getBoolean(key, true);
|
||||||
@ -536,9 +547,25 @@ public class PlaybackService extends Service implements Runnable, MediaPlayer.On
|
|||||||
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
|
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()
|
private void play()
|
||||||
{
|
{
|
||||||
if (mHeadsetOnly && !mPlugged)
|
if (mHeadsetOnly && isSpeakerOn())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mMediaPlayer.start();
|
mMediaPlayer.start();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user