Use new MediaSession API on 5.x
This commit is contained in:
parent
0e425b9198
commit
81c6527e73
@ -337,6 +337,10 @@ public final class PlaybackService extends Service
|
|||||||
* The SensorManager service.
|
* The SensorManager service.
|
||||||
*/
|
*/
|
||||||
private SensorManager mSensorManager;
|
private SensorManager mSensorManager;
|
||||||
|
/**
|
||||||
|
* A remote control client implementation
|
||||||
|
*/
|
||||||
|
private RemoteControl.Client mRemoteControlClient;
|
||||||
|
|
||||||
SongTimeline mTimeline;
|
SongTimeline mTimeline;
|
||||||
private Song mCurrentSong;
|
private Song mCurrentSong;
|
||||||
@ -495,7 +499,8 @@ public final class PlaybackService extends Service
|
|||||||
|
|
||||||
getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mObserver);
|
getContentResolver().registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mObserver);
|
||||||
|
|
||||||
RemoteControl.registerRemote(this, mAudioManager);
|
mRemoteControlClient = new RemoteControl().getClient(this);
|
||||||
|
mRemoteControlClient.registerRemote(mAudioManager);
|
||||||
|
|
||||||
mLooper = thread.getLooper();
|
mLooper = thread.getLooper();
|
||||||
mHandler = new Handler(mLooper, this);
|
mHandler = new Handler(mLooper, this);
|
||||||
@ -614,6 +619,9 @@ public final class PlaybackService extends Service
|
|||||||
if (mSensorManager != null)
|
if (mSensorManager != null)
|
||||||
mSensorManager.unregisterListener(this);
|
mSensorManager.unregisterListener(this);
|
||||||
|
|
||||||
|
if (mRemoteControlClient != null)
|
||||||
|
mRemoteControlClient.unregisterRemote();
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,7 +841,7 @@ public final class PlaybackService extends Service
|
|||||||
} else if (PrefKeys.MEDIA_BUTTON.equals(key) || PrefKeys.MEDIA_BUTTON_BEEP.equals(key)) {
|
} else if (PrefKeys.MEDIA_BUTTON.equals(key) || PrefKeys.MEDIA_BUTTON_BEEP.equals(key)) {
|
||||||
MediaButtonReceiver.reloadPreference(this);
|
MediaButtonReceiver.reloadPreference(this);
|
||||||
} else if (PrefKeys.COVER_ON_LOCKSCREEN.equals(key)) {
|
} else if (PrefKeys.COVER_ON_LOCKSCREEN.equals(key)) {
|
||||||
RemoteControl.reloadPreference();
|
mRemoteControlClient.reloadPreference();
|
||||||
} else if (PrefKeys.USE_IDLE_TIMEOUT.equals(key) || PrefKeys.IDLE_TIMEOUT.equals(key)) {
|
} else if (PrefKeys.USE_IDLE_TIMEOUT.equals(key) || PrefKeys.IDLE_TIMEOUT.equals(key)) {
|
||||||
mIdleTimeout = settings.getBoolean(PrefKeys.USE_IDLE_TIMEOUT, PrefDefaults.USE_IDLE_TIMEOUT) ? settings.getInt(PrefKeys.IDLE_TIMEOUT, PrefDefaults.IDLE_TIMEOUT) : 0;
|
mIdleTimeout = settings.getBoolean(PrefKeys.USE_IDLE_TIMEOUT, PrefDefaults.USE_IDLE_TIMEOUT) ? settings.getInt(PrefKeys.IDLE_TIMEOUT, PrefDefaults.IDLE_TIMEOUT) : 0;
|
||||||
userActionTriggered();
|
userActionTriggered();
|
||||||
@ -1055,7 +1063,7 @@ public final class PlaybackService extends Service
|
|||||||
if (mReadaheadEnabled)
|
if (mReadaheadEnabled)
|
||||||
triggerReadAhead();
|
triggerReadAhead();
|
||||||
|
|
||||||
RemoteControl.updateRemote(this, mCurrentSong, mState, mForceNotificationVisible);
|
mRemoteControlClient.updateRemote(mCurrentSong, mState, mForceNotificationVisible);
|
||||||
|
|
||||||
if (mStockBroadcast)
|
if (mStockBroadcast)
|
||||||
stockMusicBroadcast();
|
stockMusicBroadcast();
|
||||||
|
@ -1,129 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
|
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
|
||||||
* Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* it under the terms of the GNU General Public License as published by
|
||||||
* in the Software without restriction, including without limitation the rights
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* (at your option) any later version.
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* This program is distributed in the hope that it will be useful,
|
||||||
* all copies or substantial portions of the Software.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* You should have received a copy of the GNU General Public License
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.blinkenlights.android.vanilla;
|
package ch.blinkenlights.android.vanilla;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaMetadataRetriever;
|
import android.os.Build;
|
||||||
import android.media.RemoteControlClient;
|
|
||||||
|
|
||||||
|
|
||||||
public class RemoteControl {
|
public class RemoteControl {
|
||||||
/**
|
|
||||||
* Used with updateRemote method.
|
|
||||||
*/
|
|
||||||
private static RemoteControlClient sRemote;
|
|
||||||
/**
|
|
||||||
* Whether the cover should be shown. 1 for yes, 0 for no, -1 for
|
|
||||||
* uninitialized.
|
|
||||||
*/
|
|
||||||
private static int sShowCover = -1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform initialization required for RemoteControlClient.
|
* Returns a RemoteControl.Client implementation
|
||||||
*
|
|
||||||
* @param context A context to use.
|
|
||||||
* @param am The AudioManager service.
|
|
||||||
*/
|
*/
|
||||||
public static void registerRemote(Context context, AudioManager am)
|
public RemoteControl.Client getClient(Context context) {
|
||||||
{
|
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ?
|
||||||
if (!MediaButtonReceiver.useHeadsetControls(context)) {
|
new RemoteControlImplLp(context) :
|
||||||
// RemoteControlClient requires MEDIA_BUTTON intent
|
new RemoteControlImplKitKat(context) // legacy implementation, kept until we drop 4.x support
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
MediaButtonReceiver.registerMediaButton(context);
|
|
||||||
|
|
||||||
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
|
|
||||||
mediaButtonIntent.setComponent(new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName()));
|
|
||||||
PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(context, 0, mediaButtonIntent, 0);
|
|
||||||
RemoteControlClient remote = new RemoteControlClient(mediaPendingIntent);
|
|
||||||
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);
|
|
||||||
sRemote = remote;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uninitializes our cached preferences, forcing a reload
|
* Interface definition of our RemoteControl API
|
||||||
*/
|
*/
|
||||||
public static void reloadPreference()
|
public interface Client {
|
||||||
{
|
public void registerRemote(AudioManager am);
|
||||||
sShowCover = -1;
|
public void unregisterRemote();
|
||||||
}
|
public void reloadPreference();
|
||||||
|
public void updateRemote(Song song, int state, boolean keepPaused);
|
||||||
/**
|
|
||||||
* Update the remote with new metadata.
|
|
||||||
* {@link #registerRemote(Context, AudioManager)} must have been called
|
|
||||||
* first.
|
|
||||||
*
|
|
||||||
* @param context A context to use.
|
|
||||||
* @param song The song containing the new metadata.
|
|
||||||
* @param state PlaybackService state, used to determine playback state.
|
|
||||||
* @param keepPaused whether or not to keep the remote updated in paused mode
|
|
||||||
*/
|
|
||||||
public static void updateRemote(Context context, Song song, int state, boolean keepPaused)
|
|
||||||
{
|
|
||||||
RemoteControlClient remote = sRemote;
|
|
||||||
if (remote == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
boolean isPlaying = ((state & PlaybackService.FLAG_PLAYING) != 0);
|
|
||||||
|
|
||||||
if (sShowCover == -1) {
|
|
||||||
SharedPreferences settings = PlaybackService.getSettings(context);
|
|
||||||
sShowCover = settings.getBoolean(PrefKeys.COVER_ON_LOCKSCREEN, PrefDefaults.COVER_ON_LOCKSCREEN) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
remote.setPlaybackState(isPlaying ? RemoteControlClient.PLAYSTATE_PLAYING : RemoteControlClient.PLAYSTATE_PAUSED);
|
|
||||||
RemoteControlClient.MetadataEditor editor = remote.editMetadata(true);
|
|
||||||
if (song != null) {
|
|
||||||
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, song.artist);
|
|
||||||
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, song.album);
|
|
||||||
editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, song.title);
|
|
||||||
Bitmap bitmap = song.getCover(context);
|
|
||||||
if (bitmap != null && sShowCover == 1 && (isPlaying || keepPaused)) {
|
|
||||||
// Create a copy of the cover art, since RemoteControlClient likes
|
|
||||||
// to recycle what we give it.
|
|
||||||
bitmap = bitmap.copy(Bitmap.Config.RGB_565, false);
|
|
||||||
} else {
|
|
||||||
// Some lockscreen implementations fail to clear the cover artwork
|
|
||||||
// if we send a null bitmap. We are creating a 16x16 transparent
|
|
||||||
// bitmap to work around this limitation.
|
|
||||||
bitmap = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
|
|
||||||
}
|
|
||||||
editor.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, bitmap);
|
|
||||||
}
|
|
||||||
editor.apply();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
|
||||||
|
* Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.blinkenlights.android.vanilla;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.MediaMetadataRetriever;
|
||||||
|
import android.media.RemoteControlClient;
|
||||||
|
|
||||||
|
|
||||||
|
public class RemoteControlImplKitKat implements RemoteControl.Client {
|
||||||
|
/**
|
||||||
|
* Context of this instance
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* Used with updateRemote method.
|
||||||
|
*/
|
||||||
|
private RemoteControlClient mRemote;
|
||||||
|
/**
|
||||||
|
* Whether the cover should be shown. 1 for yes, 0 for no, -1 for
|
||||||
|
* uninitialized.
|
||||||
|
*/
|
||||||
|
private int mShowCover = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param context The context to use
|
||||||
|
*/
|
||||||
|
public RemoteControlImplKitKat(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform initialization required for RemoteControlClient.
|
||||||
|
*
|
||||||
|
* @param am The AudioManager service.
|
||||||
|
*/
|
||||||
|
public void registerRemote(AudioManager am)
|
||||||
|
{
|
||||||
|
if (!MediaButtonReceiver.useHeadsetControls(mContext)) {
|
||||||
|
// RemoteControlClient requires MEDIA_BUTTON intent
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaButtonReceiver.registerMediaButton(mContext);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
mRemote = remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterRemote() {
|
||||||
|
// we should probably call am.unregisterRemoteControlClient but we never did and i'm not touching the legacy implementation.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninitializes our cached preferences, forcing a reload
|
||||||
|
*/
|
||||||
|
public void reloadPreference()
|
||||||
|
{
|
||||||
|
mShowCover = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the remote with new metadata.
|
||||||
|
* {@link #registerRemote(Context, AudioManager)} must have been called
|
||||||
|
* first.
|
||||||
|
*
|
||||||
|
* @param song The song containing the new metadata.
|
||||||
|
* @param state PlaybackService state, used to determine playback state.
|
||||||
|
* @param keepPaused whether or not to keep the remote updated in paused mode
|
||||||
|
*/
|
||||||
|
public void updateRemote(Song song, int state, boolean keepPaused)
|
||||||
|
{
|
||||||
|
RemoteControlClient remote = mRemote;
|
||||||
|
if (remote == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean isPlaying = ((state & PlaybackService.FLAG_PLAYING) != 0);
|
||||||
|
|
||||||
|
if (mShowCover == -1) {
|
||||||
|
SharedPreferences settings = PlaybackService.getSettings(mContext);
|
||||||
|
mShowCover = settings.getBoolean(PrefKeys.COVER_ON_LOCKSCREEN, PrefDefaults.COVER_ON_LOCKSCREEN) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote.setPlaybackState(isPlaying ? RemoteControlClient.PLAYSTATE_PLAYING : RemoteControlClient.PLAYSTATE_PAUSED);
|
||||||
|
RemoteControlClient.MetadataEditor editor = remote.editMetadata(true);
|
||||||
|
if (song != null) {
|
||||||
|
editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, song.artist);
|
||||||
|
editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, song.album);
|
||||||
|
editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, song.title);
|
||||||
|
Bitmap bitmap = song.getCover(mContext);
|
||||||
|
if (bitmap != null && mShowCover == 1 && (isPlaying || keepPaused)) {
|
||||||
|
// Create a copy of the cover art, since RemoteControlClient likes
|
||||||
|
// to recycle what we give it.
|
||||||
|
bitmap = bitmap.copy(Bitmap.Config.RGB_565, false);
|
||||||
|
} else {
|
||||||
|
// Some lockscreen implementations fail to clear the cover artwork
|
||||||
|
// if we send a null bitmap. We are creating a 16x16 transparent
|
||||||
|
// bitmap to work around this limitation.
|
||||||
|
bitmap = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
editor.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, bitmap);
|
||||||
|
}
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
}
|
122
src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java
Normal file
122
src/ch/blinkenlights/android/vanilla/RemoteControlImplLp.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Adrian Ulrich <adrian@blinkenlights.ch>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.blinkenlights.android.vanilla;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class RemoteControlImplLp implements RemoteControl.Client {
|
||||||
|
/**
|
||||||
|
* Context of this instance
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* Objects MediaSession handle
|
||||||
|
*/
|
||||||
|
private MediaSession mMediaSession;
|
||||||
|
/**
|
||||||
|
* Whether the cover should be shown. 1 for yes, 0 for no, -1 for
|
||||||
|
* uninitialized.
|
||||||
|
*/
|
||||||
|
private int mShowCover = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param context The context to use
|
||||||
|
*/
|
||||||
|
public RemoteControlImplLp(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new MediaSession on the device
|
||||||
|
*
|
||||||
|
* @param am The AudioManager service. (unused)
|
||||||
|
*/
|
||||||
|
public void registerRemote(AudioManager am) {
|
||||||
|
mMediaSession = new MediaSession(mContext, "VanillaMusic");
|
||||||
|
mMediaSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
|
||||||
|
mMediaSession.setActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a registered media session
|
||||||
|
*/
|
||||||
|
public void unregisterRemote() {
|
||||||
|
mMediaSession.setActive(false);
|
||||||
|
mMediaSession.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninitializes our cached preferences, forcing a reload
|
||||||
|
*/
|
||||||
|
public void reloadPreference() {
|
||||||
|
mShowCover = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the remote with new metadata.
|
||||||
|
* {@link #registerRemote(AudioManager)} must have been called
|
||||||
|
* first.
|
||||||
|
*
|
||||||
|
* @param song The song containing the new metadata.
|
||||||
|
* @param state PlaybackService state, used to determine playback state.
|
||||||
|
* @param keepPaused whether or not to keep the remote updated in paused mode
|
||||||
|
*/
|
||||||
|
public void updateRemote(Song song, int state, boolean keepPaused) {
|
||||||
|
MediaSession session = mMediaSession;
|
||||||
|
if (session == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean isPlaying = ((state & PlaybackService.FLAG_PLAYING) != 0);
|
||||||
|
|
||||||
|
if (mShowCover == -1) {
|
||||||
|
SharedPreferences settings = PlaybackService.getSettings(mContext);
|
||||||
|
mShowCover = settings.getBoolean(PrefKeys.COVER_ON_LOCKSCREEN, PrefDefaults.COVER_ON_LOCKSCREEN) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (song != null) {
|
||||||
|
Bitmap bitmap = null;
|
||||||
|
if (mShowCover == 1 && (isPlaying || keepPaused)) {
|
||||||
|
bitmap = song.getCover(mContext);
|
||||||
|
if (bitmap != null)
|
||||||
|
bitmap.copy(Bitmap.Config.ARGB_8888, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
session.setMetadata(new MediaMetadata.Builder()
|
||||||
|
.putString(MediaMetadata.METADATA_KEY_ARTIST, song.artist)
|
||||||
|
.putString(MediaMetadata.METADATA_KEY_ALBUM, song.album)
|
||||||
|
.putString(MediaMetadata.METADATA_KEY_TITLE, song.title)
|
||||||
|
.putLong(MediaMetadata.METADATA_KEY_DURATION, song.duration)
|
||||||
|
.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
int playbackState = (isPlaying ? PlaybackState.STATE_PLAYING : PlaybackState.STATE_PAUSED);
|
||||||
|
session.setPlaybackState(new PlaybackState.Builder()
|
||||||
|
.setState(playbackState, PlaybackState.PLAYBACK_POSITION_UNKNOWN , 1.0f).build());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user