aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java119
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java32
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientHelper.java27
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java71
4 files changed, 172 insertions, 77 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
index bec6c727..2de8eb46 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
@@ -18,22 +18,14 @@
*/
package github.daneren2005.dsub.service;
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.media.AudioManager;
-import android.media.MediaMetadataRetriever;
-import android.media.MediaPlayer;
-import android.media.RemoteControlClient;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.PowerManager;
-import android.util.Log;
+import static github.daneren2005.dsub.domain.PlayerState.COMPLETED;
+import static github.daneren2005.dsub.domain.PlayerState.DOWNLOADING;
+import static github.daneren2005.dsub.domain.PlayerState.IDLE;
+import static github.daneren2005.dsub.domain.PlayerState.PAUSED;
+import static github.daneren2005.dsub.domain.PlayerState.PREPARED;
+import static github.daneren2005.dsub.domain.PlayerState.PREPARING;
+import static github.daneren2005.dsub.domain.PlayerState.STARTED;
+import static github.daneren2005.dsub.domain.PlayerState.STOPPED;
import github.daneren2005.dsub.audiofx.EqualizerController;
import github.daneren2005.dsub.audiofx.VisualizerController;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -41,10 +33,12 @@ import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.RepeatMode;
import github.daneren2005.dsub.receiver.MediaButtonIntentReceiver;
import github.daneren2005.dsub.util.CancellableTask;
+import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.LRUCache;
import github.daneren2005.dsub.util.ShufflePlayBuffer;
import github.daneren2005.dsub.util.SimpleServiceBinder;
import github.daneren2005.dsub.util.Util;
+import github.daneren2005.dsub.util.compat.RemoteControlClientHelper;
import java.io.File;
import java.util.ArrayList;
@@ -52,8 +46,17 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import static github.daneren2005.dsub.domain.PlayerState.*;
-import github.daneren2005.dsub.util.*;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.util.Log;
/**
* @author Sindre Mehus
@@ -71,8 +74,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
public static final String CMD_NEXT = "github.daneren2005.dsub.CMD_NEXT";
- private RemoteControlClient mRemoteControlClient;
- private ImageLoader imageLoader;
+ private RemoteControlClientHelper mRemoteControl;
private final IBinder binder = new SimpleServiceBinder<DownloadService>(this);
private MediaPlayer mediaPlayer;
@@ -121,12 +123,9 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
}
- @TargetApi(14)
@Override
public void onCreate() {
super.onCreate();
-
- imageLoader = new ImageLoader(this);
mediaPlayer = new MediaPlayer();
mediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
@@ -139,36 +138,15 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
});
- if (Build.VERSION.SDK_INT >= 14) {
-
- Util.requestAudioFocus(this);
- Util.registerMediaButtonEventReceiver(this);
-
- // Use the remote control APIs (if available) to set the playback state
- if (mRemoteControlClient == null) {
- AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- ComponentName mediaButtonReceiverComponent = new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName());
- // audioManager.registerMediaButtonEventReceiver(mediaButtonReceiverComponent);
- // build the PendingIntent for the remote control client
- Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
- mediaButtonIntent.setComponent(mediaButtonReceiverComponent);
- PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
- // create and register the remote control client
- mRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
- audioManager.registerRemoteControlClient(mRemoteControlClient);
- }
-
- mRemoteControlClient.setPlaybackState(
- RemoteControlClient.PLAYSTATE_STOPPED);
+ Util.requestAudioFocus(this);
+ Util.registerMediaButtonEventReceiver(this);
- mRemoteControlClient.setTransportControlFlags(
- RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
- RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
- RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE |
- RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS |
- RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
- RemoteControlClient.FLAG_KEY_MEDIA_STOP);
- }
+ if (mRemoteControl == null) {
+ // Use the remote control APIs (if available) to set the playback state
+ mRemoteControl = RemoteControlClientHelper.createInstance();
+ ComponentName mediaButtonReceiverComponent = new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName());
+ mRemoteControl.register(this, mediaButtonReceiverComponent);
+ }
if (equalizerAvailable) {
equalizerController = new EqualizerController(this, mediaPlayer);
@@ -194,12 +172,13 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
@Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ super.onStartCommand(intent, flags, startId);
lifecycleSupport.onStart(intent);
+ return START_NOT_STICKY;
}
- @Override
+ @Override
public void onDestroy() {
super.onDestroy();
lifecycleSupport.onDestroy();
@@ -211,6 +190,10 @@ public class DownloadServiceImpl extends Service implements DownloadService {
if (visualizerController != null) {
visualizerController.release();
}
+ if (mRemoteControl != null) {
+ mRemoteControl.unregister(this);
+ mRemoteControl = null;
+ }
instance = null;
}
@@ -440,7 +423,6 @@ public class DownloadServiceImpl extends Service implements DownloadService {
}
}
- @TargetApi(14)
synchronized void setCurrentPlaying(DownloadFile currentPlaying, boolean showNotification) {
this.currentPlaying = currentPlaying;
@@ -457,23 +439,9 @@ public class DownloadServiceImpl extends Service implements DownloadService {
Util.hidePlayingNotification(this, this, handler);
}
- if (mRemoteControlClient != null) {
- MusicDirectory.Entry currentSong = ((currentPlaying == null) ? null: currentPlaying.getSong());
- // Update the remote controls
- mRemoteControlClient.editMetadata(true)
- .putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, currentSong == null ? null : currentSong.getArtist())
- .putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, currentSong == null ? null : currentSong.getAlbum())
- .putString(MediaMetadataRetriever.METADATA_KEY_TITLE, currentSong == null ? null : currentSong.getTitle())
- .putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, (currentSong == null) ? 0 : ((currentSong.getDuration() == null) ? 0 : currentSong.getDuration()))
- .apply();
- if (currentSong == null) {
- mRemoteControlClient.editMetadata(true)
- .putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, null)
- .apply();
- } else {
- imageLoader.loadImage(this, mRemoteControlClient, currentSong);
- }
- }
+ MusicDirectory.Entry currentSong = (currentPlaying == null) ? null: currentPlaying.getSong();
+ mRemoteControl.updateMetadata(this, currentSong);
+
}
@Override
@@ -683,7 +651,6 @@ public class DownloadServiceImpl extends Service implements DownloadService {
return playerState;
}
- @TargetApi(14)
synchronized void setPlayerState(PlayerState playerState) {
Log.i(TAG, this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")");
@@ -696,9 +663,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
Util.broadcastPlaybackStatusChange(this, playerState);
this.playerState = playerState;
- if (mRemoteControlClient != null) {
- mRemoteControlClient.setPlaybackState(playerState.getRemoteControlClientPlayState());
- }
+ mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState());
if (show) {
Util.showPlayingNotification(this, this, handler, currentPlaying.getSong());
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java
new file mode 100644
index 00000000..c3f3f70c
--- /dev/null
+++ b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientBase.java
@@ -0,0 +1,32 @@
+package github.daneren2005.dsub.util.compat;
+
+import github.daneren2005.dsub.domain.MusicDirectory.Entry;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+
+public class RemoteControlClientBase extends RemoteControlClientHelper {
+
+ private static final String TAG = RemoteControlClientBase.class.getSimpleName();
+
+ @Override
+ public void register(Context context, ComponentName mediaButtonReceiverComponent) {
+ Log.w(TAG, "RemoteControlClient requires Android API level 14 or higher.");
+ }
+
+ @Override
+ public void unregister(Context context) {
+ Log.w(TAG, "RemoteControlClient requires Android API level 14 or higher.");
+ }
+
+ @Override
+ public void setPlaybackState(int state) {
+ Log.w(TAG, "RemoteControlClient requires Android API level 14 or higher.");
+ }
+
+ @Override
+ public void updateMetadata(Context context, Entry currentSong) {
+ Log.w(TAG, "RemoteControlClient requires Android API level 14 or higher.");
+ }
+
+}
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientHelper.java b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientHelper.java
new file mode 100644
index 00000000..ddaa9f43
--- /dev/null
+++ b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientHelper.java
@@ -0,0 +1,27 @@
+package github.daneren2005.dsub.util.compat;
+
+import github.daneren2005.dsub.domain.MusicDirectory;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Build;
+
+public abstract class RemoteControlClientHelper {
+
+ public static RemoteControlClientHelper createInstance() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ return new RemoteControlClientBase();
+ } else {
+ return new RemoteControlClientICS();
+ }
+ }
+
+ protected RemoteControlClientHelper() {
+ // Avoid instantiation
+ }
+
+ public abstract void register(final Context context, final ComponentName mediaButtonReceiverComponent);
+ public abstract void unregister(final Context context);
+ public abstract void setPlaybackState(final int state);
+ public abstract void updateMetadata(final Context context, final MusicDirectory.Entry currentSong);
+
+}
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java
new file mode 100644
index 00000000..c5b09876
--- /dev/null
+++ b/subsonic-android/src/github/daneren2005/dsub/util/compat/RemoteControlClientICS.java
@@ -0,0 +1,71 @@
+package github.daneren2005.dsub.util.compat;
+
+import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.util.ImageLoader;
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.MediaMetadataRetriever;
+import android.media.RemoteControlClient;
+
+@TargetApi(14)
+public class RemoteControlClientICS extends RemoteControlClientHelper {
+
+ private RemoteControlClient mRemoteControl;
+
+ public void register(final Context context, final ComponentName mediaButtonReceiverComponent) {
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
+ // build the PendingIntent for the remote control client
+ Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.setComponent(mediaButtonReceiverComponent);
+ PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, mediaButtonIntent, 0);
+
+ // create and register the remote control client
+ mRemoteControl = new RemoteControlClient(mediaPendingIntent);
+ audioManager.registerRemoteControlClient(mRemoteControl);
+
+ mRemoteControl.setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
+
+ mRemoteControl.setTransportControlFlags(
+ RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
+ RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
+ RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE |
+ RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS |
+ RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
+ RemoteControlClient.FLAG_KEY_MEDIA_STOP);
+ }
+
+ public void unregister(final Context context) {
+ if (mRemoteControl != null) {
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ audioManager.unregisterRemoteControlClient(mRemoteControl);
+ }
+ }
+
+ public void setPlaybackState(final int state) {
+ mRemoteControl.setPlaybackState(state);
+ }
+
+ public void updateMetadata(final Context context, final MusicDirectory.Entry currentSong) {
+ // Update the remote controls
+ mRemoteControl.editMetadata(true)
+ .putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, (currentSong == null) ? null : currentSong.getArtist())
+ .putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, (currentSong == null) ? null : currentSong.getAlbum())
+ .putString(MediaMetadataRetriever.METADATA_KEY_TITLE, (currentSong) == null ? null : currentSong.getTitle())
+ .putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, (currentSong == null) ?
+ 0 : ((currentSong.getDuration() == null) ? 0 : currentSong.getDuration()))
+ .apply();
+ if (currentSong == null) {
+ mRemoteControl.editMetadata(true)
+ .putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, null)
+ .apply();
+ } else {
+ new ImageLoader(context).loadImage(context, mRemoteControl, currentSong);
+ }
+ }
+
+}