From deb5637c17a55b16eec2617262f9162b367ef24b Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sun, 20 Dec 2015 22:01:11 +0100 Subject: [PATCH] Move button handling code to RemoteControl implementations --- .../android/vanilla/MediaButtonReceiver.java | 35 +------------- .../android/vanilla/PlaybackActivity.java | 1 - .../android/vanilla/PlaybackService.java | 4 +- .../android/vanilla/RemoteControl.java | 3 +- .../vanilla/RemoteControlImplKitKat.java | 24 ++++++---- .../android/vanilla/RemoteControlImplLp.java | 47 +++++++++++++++---- 6 files changed, 55 insertions(+), 59 deletions(-) diff --git a/src/ch/blinkenlights/android/vanilla/MediaButtonReceiver.java b/src/ch/blinkenlights/android/vanilla/MediaButtonReceiver.java index a01d2a34..8db812b1 100644 --- a/src/ch/blinkenlights/android/vanilla/MediaButtonReceiver.java +++ b/src/ch/blinkenlights/android/vanilla/MediaButtonReceiver.java @@ -96,11 +96,6 @@ public class MediaButtonReceiver extends BroadcastReceiver { { sUseControls = -1; sBeep = -1; - if (useHeadsetControls(context)) { - registerMediaButton(context); - } else { - unregisterMediaButton(context); - } } /** @@ -109,7 +104,7 @@ public class MediaButtonReceiver extends BroadcastReceiver { * * @param context A context to use. */ - public static boolean useHeadsetControls(Context context) + private static boolean useHeadsetControls(Context context) { if (sUseControls == -1) { SharedPreferences settings = PlaybackService.getSettings(context); @@ -181,34 +176,6 @@ public class MediaButtonReceiver extends BroadcastReceiver { return true; } - /** - * Request focus on the media buttons from AudioManager if media buttons - * are enabled. - * - * @param context A context to use. - */ - public static void registerMediaButton(Context context) - { - if (!useHeadsetControls(context)) - return; - - AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); - ComponentName receiver = new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName()); - audioManager.registerMediaButtonEventReceiver(receiver); - } - - /** - * Unregister the media buttons from AudioManager. - * - * @param context A context to use. - */ - public static void unregisterMediaButton(Context context) - { - AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); - ComponentName receiver = new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName()); - audioManager.unregisterMediaButtonEventReceiver(receiver); - } - @Override public void onReceive(Context context, Intent intent) { diff --git a/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java b/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java index 0d7da392..fc2b7f29 100644 --- a/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java +++ b/src/ch/blinkenlights/android/vanilla/PlaybackActivity.java @@ -135,7 +135,6 @@ public abstract class PlaybackActivity extends Activity public void onResume() { super.onResume(); - MediaButtonReceiver.registerMediaButton(this); if (PlaybackService.hasInstance()) { PlaybackService service = PlaybackService.get(this); service.userActionTriggered(); diff --git a/src/ch/blinkenlights/android/vanilla/PlaybackService.java b/src/ch/blinkenlights/android/vanilla/PlaybackService.java index 60429efa..43a50759 100644 --- a/src/ch/blinkenlights/android/vanilla/PlaybackService.java +++ b/src/ch/blinkenlights/android/vanilla/PlaybackService.java @@ -500,7 +500,7 @@ public final class PlaybackService extends Service getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mObserver); mRemoteControlClient = new RemoteControl().getClient(this); - mRemoteControlClient.registerRemote(mAudioManager); + mRemoteControlClient.registerRemote(); mLooper = thread.getLooper(); mHandler = new Handler(mLooper, this); @@ -580,8 +580,6 @@ public final class PlaybackService extends Service stopForeground(true); // sometimes required to clear notification updateNotification(); } - - MediaButtonReceiver.registerMediaButton(this); } return START_NOT_STICKY; diff --git a/src/ch/blinkenlights/android/vanilla/RemoteControl.java b/src/ch/blinkenlights/android/vanilla/RemoteControl.java index 7c9004aa..f6e39799 100644 --- a/src/ch/blinkenlights/android/vanilla/RemoteControl.java +++ b/src/ch/blinkenlights/android/vanilla/RemoteControl.java @@ -18,7 +18,6 @@ package ch.blinkenlights.android.vanilla; import android.content.Context; -import android.media.AudioManager; import android.os.Build; @@ -38,7 +37,7 @@ public class RemoteControl { * Interface definition of our RemoteControl API */ public interface Client { - public void registerRemote(AudioManager am); + public void registerRemote(); public void unregisterRemote(); public void reloadPreference(); public void updateRemote(Song song, int state, boolean keepPaused); diff --git a/src/ch/blinkenlights/android/vanilla/RemoteControlImplKitKat.java b/src/ch/blinkenlights/android/vanilla/RemoteControlImplKitKat.java index fdc22105..2b425c4e 100644 --- a/src/ch/blinkenlights/android/vanilla/RemoteControlImplKitKat.java +++ b/src/ch/blinkenlights/android/vanilla/RemoteControlImplKitKat.java @@ -63,31 +63,37 @@ public class RemoteControlImplKitKat implements RemoteControl.Client { * * @param am The AudioManager service. */ - public void registerRemote(AudioManager am) + public void registerRemote() { - if (!MediaButtonReceiver.useHeadsetControls(mContext)) { - // RemoteControlClient requires MEDIA_BUTTON intent - return; - } - - MediaButtonReceiver.registerMediaButton(mContext); + // Receive 'background' play button events + AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); + ComponentName receiver = new ComponentName(mContext.getPackageName(), MediaButtonReceiver.class.getName()); + audioManager.registerMediaButtonEventReceiver(receiver); Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); mediaButtonIntent.setComponent(new ComponentName(mContext.getPackageName(), MediaButtonReceiver.class.getName())); PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(mContext, 0, mediaButtonIntent, 0); RemoteControlClient remote = new RemoteControlClient(mediaPendingIntent); + + // Things we can do (eg: buttons to display on lock screen) int flags = RemoteControlClient.FLAG_KEY_MEDIA_NEXT | RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE | RemoteControlClient.FLAG_KEY_MEDIA_PLAY | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE; remote.setTransportControlFlags(flags); - am.registerRemoteControlClient(remote); + + audioManager.registerRemoteControlClient(remote); mRemote = remote; } + /** + * Unregisters a remote control client + */ public void unregisterRemote() { - // we should probably call am.unregisterRemoteControlClient but we never did and i'm not touching the legacy implementation. + AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); + ComponentName receiver = new ComponentName(mContext.getPackageName(), MediaButtonReceiver.class.getName()); + audioManager.unregisterMediaButtonEventReceiver(receiver); } /** diff --git a/src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java b/src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java index 17731f9b..d8c84a4e 100644 --- a/src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java +++ b/src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java @@ -17,15 +17,16 @@ package ch.blinkenlights.android.vanilla; +import android.app.PendingIntent; import android.content.Context; +import android.content.ComponentName; +import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; -import android.media.AudioManager; import android.media.MediaMetadata; import android.media.session.MediaSession; import android.media.session.PlaybackState; - - +import android.view.KeyEvent; public class RemoteControlImplLp implements RemoteControl.Client { /** @@ -53,13 +54,34 @@ public class RemoteControlImplLp implements RemoteControl.Client { /** * Registers a new MediaSession on the device - * - * @param am The AudioManager service. (unused) */ - public void registerRemote(AudioManager am) { + public void registerRemote() { mMediaSession = new MediaSession(mContext, "VanillaMusic"); - mMediaSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); - mMediaSession.setActive(true); + + mMediaSession.setCallback(new MediaSession.Callback() { + @Override + public void onPause() { + MediaButtonReceiver.processKey(mContext, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)); + } + public void onPlay() { + MediaButtonReceiver.processKey(mContext, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)); + } + @Override + public void onSkipToNext() { + MediaButtonReceiver.processKey(mContext, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT)); + } + public void onSkipToPrevious() { + MediaButtonReceiver.processKey(mContext, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); + } + }); + + // This intent will be used to receive button events while our session is NOT active + Intent intent = new Intent(); + intent.setComponent(new ComponentName(mContext.getPackageName(), MediaButtonReceiver.class.getName())); + PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); + + mMediaSession.setMediaButtonReceiver(pendingIntent); + mMediaSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); } /** @@ -79,7 +101,7 @@ public class RemoteControlImplLp implements RemoteControl.Client { /** * Update the remote with new metadata. - * {@link #registerRemote(AudioManager)} must have been called + * {@link #registerRemote()} must have been called * first. * * @param song The song containing the new metadata. @@ -116,7 +138,12 @@ public class RemoteControlImplLp implements RemoteControl.Client { } int playbackState = (isPlaying ? PlaybackState.STATE_PLAYING : PlaybackState.STATE_PAUSED); + session.setPlaybackState(new PlaybackState.Builder() - .setState(playbackState, PlaybackState.PLAYBACK_POSITION_UNKNOWN , 1.0f).build()); + .setState(playbackState, PlaybackState.PLAYBACK_POSITION_UNKNOWN , 1.0f) + .setActions(PlaybackState.ACTION_PLAY | PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY_PAUSE | + PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS) + .build()); + mMediaSession.setActive(true); } }