diff options
Diffstat (limited to 'subsonic-android')
7 files changed, 117 insertions, 66 deletions
diff --git a/subsonic-android/AndroidManifest.xml b/subsonic-android/AndroidManifest.xml index 18197d58..7ab94ba4 100644 --- a/subsonic-android/AndroidManifest.xml +++ b/subsonic-android/AndroidManifest.xml @@ -2,8 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="github.daneren2005.dsub"
android:installLocation="internalOnly"
- android:versionCode="42"
- android:versionName="3.8.4">
+ android:versionCode="45"
+ android:versionName="3.8.6">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
diff --git a/subsonic-android/res/values/strings.xml b/subsonic-android/res/values/strings.xml index c9c7c991..577563c9 100644 --- a/subsonic-android/res/values/strings.xml +++ b/subsonic-android/res/values/strings.xml @@ -9,8 +9,8 @@ <string name="common.play_shuffled">Play shuffled</string>
<string name="common.play_next">Play next</string>
<string name="common.play_last">Play last</string>
- <string name="common.download">Download</string>
- <string name="common.pin">Cache</string>
+ <string name="common.download">Cache</string>
+ <string name="common.pin">Permanent Cache</string>
<string name="common.delete">Delete</string>
<string name="common.star">Star</string>
<string name="common.unstar">Unstar</string>
diff --git a/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java b/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java index ef0ab956..021868b9 100644 --- a/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java +++ b/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java @@ -220,19 +220,19 @@ public class DSubWidgetProvider extends AppWidgetProvider { // Emulate media button clicks. intent = new Intent("DSub.PLAY_PAUSE"); intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_play, pendingIntent); intent = new Intent("DSub.NEXT"); // Use a unique action name to ensure a different PendingIntent to be created. intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT)); + intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_next, pendingIntent); intent = new Intent("DSub.PREVIOUS"); // Use a unique action name to ensure a different PendingIntent to be created. intent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); + intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_previous, pendingIntent); } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java index 1457c4da..3bc5f4a9 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java @@ -125,6 +125,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { private Timer sleepTimer; private int timerDuration; + private boolean autoPlayStart = false; static { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { @@ -152,10 +153,14 @@ public class DownloadServiceImpl extends Service implements DownloadService { } }); - Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); - i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId()); - i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName()); - sendBroadcast(i); + try { + Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); + i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId()); + i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName()); + sendBroadcast(i); + } catch(Throwable e) { + // Froyo or lower + } mediaPlayerLooper = Looper.myLooper(); mediaPlayerHandler = new Handler(mediaPlayerLooper); @@ -179,7 +184,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { SharedPreferences prefs = Util.getPreferences(this); try { timerDuration = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, "5")); - } catch(Exception e) { + } catch(Throwable e) { timerDuration = 5; } sleepTimer = null; @@ -211,10 +216,14 @@ public class DownloadServiceImpl extends Service implements DownloadService { } lifecycleSupport.onDestroy(); - Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); - i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId()); - i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName()); - sendBroadcast(i); + try { + Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); + i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId()); + i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName()); + sendBroadcast(i); + } catch(Throwable e) { + // Froyo or lower + } mediaPlayer.release(); if(nextMediaPlayer != null) { @@ -313,10 +322,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { public void restore(List<MusicDirectory.Entry> songs, int currentPlayingIndex, int currentPlayingPosition) { download(songs, false, false, false, false); if (currentPlayingIndex != -1) { - play(currentPlayingIndex, false); + play(currentPlayingIndex, autoPlayStart); if (currentPlaying.isCompleteFileAvailable()) { - doPlay(currentPlaying, currentPlayingPosition, false); + doPlay(currentPlaying, currentPlayingPosition, autoPlayStart); } + autoPlayStart = false; } } @@ -650,6 +660,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { if (playerState == PAUSED || playerState == COMPLETED || playerState == STOPPED) { start(); } else if (playerState == STOPPED || playerState == IDLE) { + autoPlayStart = true; play(); } else if (playerState == STARTED) { pause(); @@ -823,7 +834,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { } boolean show = playerState == PlayerState.STARTED; - boolean pause = this.playerState == STARTED && playerState == PlayerState.PAUSED; + boolean pause = playerState == PlayerState.PAUSED; boolean hide = playerState == PlayerState.STOPPED; Util.broadcastPlaybackStatusChange(this, playerState); @@ -1063,7 +1074,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { } nextMediaPlayer = new MediaPlayer(); nextMediaPlayer.setWakeMode(DownloadServiceImpl.this, PowerManager.PARTIAL_WAKE_LOCK); - nextMediaPlayer.setAudioSessionId(mediaPlayer.getAudioSessionId()); + try { + nextMediaPlayer.setAudioSessionId(mediaPlayer.getAudioSessionId()); + } catch(Throwable e) { + nextMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + } nextMediaPlayer.setDataSource(file.getPath()); setNextPlayerState(PREPARING); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java index a8600252..98e86706 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import android.content.BroadcastReceiver; import android.content.Context; @@ -31,6 +32,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.RemoteControlClient; import android.os.AsyncTask; +import android.os.Build; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; @@ -55,6 +57,7 @@ public class DownloadServiceLifecycleSupport { private BroadcastReceiver ejectEventReceiver; private PhoneStateListener phoneStateListener; private boolean externalStorageAvailable= true; + private ReentrantLock lock = new ReentrantLock(); /** * This receiver manages the intent that could come from other applications. @@ -182,7 +185,11 @@ public class DownloadServiceLifecycleSupport { } public void serializeDownloadQueue() { - new SerializeTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + new SerializeTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + new SerializeTask().execute(); + } } public void serializeDownloadQueueNow() { @@ -199,7 +206,11 @@ public class DownloadServiceLifecycleSupport { } private void deserializeDownloadQueue() { - new DeserializeTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + new DeserializeTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + new DeserializeTask().execute(); + } } private void deserializeDownloadQueueNow() { State state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER); @@ -214,42 +225,51 @@ public class DownloadServiceLifecycleSupport { } private void handleKeyEvent(KeyEvent event) { - if (event.getAction() != KeyEvent.ACTION_DOWN || event.getRepeatCount() > 0) { - return; - } - - switch (event.getKeyCode()) { - case RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_HEADSETHOOK: - downloadService.togglePlayPause(); - break; - case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS: - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - downloadService.previous(); - break; - case RemoteControlClient.FLAG_KEY_MEDIA_NEXT: - case KeyEvent.KEYCODE_MEDIA_NEXT: - if (downloadService.getCurrentPlayingIndex() < downloadService.size() - 1) { - downloadService.next(); - } - break; - case RemoteControlClient.FLAG_KEY_MEDIA_STOP: - case KeyEvent.KEYCODE_MEDIA_STOP: - downloadService.stop(); - break; - case RemoteControlClient.FLAG_KEY_MEDIA_PLAY: - case KeyEvent.KEYCODE_MEDIA_PLAY: - if(downloadService.getPlayerState() != PlayerState.STARTED) { - downloadService.start(); - } - break; - case RemoteControlClient.FLAG_KEY_MEDIA_PAUSE: - case KeyEvent.KEYCODE_MEDIA_PAUSE: - downloadService.pause(); - default: - break; - } + if(event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() > 0) { + switch (event.getKeyCode()) { + case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + downloadService.seekTo(downloadService.getPlayerPosition() - 10000); + break; + case RemoteControlClient.FLAG_KEY_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_NEXT: + downloadService.seekTo(downloadService.getPlayerPosition() + 10000); + break; + } + } else if(event.getAction() == KeyEvent.ACTION_UP) { + switch (event.getKeyCode()) { + case RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_HEADSETHOOK: + downloadService.togglePlayPause(); + break; + case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS: + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + downloadService.previous(); + break; + case RemoteControlClient.FLAG_KEY_MEDIA_NEXT: + case KeyEvent.KEYCODE_MEDIA_NEXT: + if (downloadService.getCurrentPlayingIndex() < downloadService.size() - 1) { + downloadService.next(); + } + break; + case RemoteControlClient.FLAG_KEY_MEDIA_STOP: + case KeyEvent.KEYCODE_MEDIA_STOP: + downloadService.stop(); + break; + case RemoteControlClient.FLAG_KEY_MEDIA_PLAY: + case KeyEvent.KEYCODE_MEDIA_PLAY: + if(downloadService.getPlayerState() != PlayerState.STARTED) { + downloadService.start(); + } + break; + case RemoteControlClient.FLAG_KEY_MEDIA_PAUSE: + case KeyEvent.KEYCODE_MEDIA_PAUSE: + downloadService.pause(); + default: + break; + } + } } /** @@ -292,14 +312,25 @@ public class DownloadServiceLifecycleSupport { private class SerializeTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { - serializeDownloadQueueNow(); + if(lock.tryLock()) { + try { + serializeDownloadQueueNow(); + } finally { + lock.unlock(); + } + } return null; } } private class DeserializeTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { - deserializeDownloadQueueNow(); + try { + lock.lock(); + deserializeDownloadQueueNow(); + } finally { + lock.unlock(); + } return null; } } diff --git a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java index 3f8876b9..c239fa43 100644 --- a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java +++ b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java @@ -46,8 +46,13 @@ public class Updater { updaters.add(new Updater373());
SharedPreferences prefs = Util.getPreferences(context);
- int lastVersion = prefs.getInt(Constants.LAST_VERSION, 372);
- if(version > lastVersion) {
+ int lastVersion = prefs.getInt(Constants.LAST_VERSION, 0);
+ if(lastVersion == 0) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(Constants.LAST_VERSION, version);
+ editor.commit();
+ }
+ else if(version > lastVersion) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(Constants.LAST_VERSION, version);
editor.commit();
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Util.java b/subsonic-android/src/github/daneren2005/dsub/util/Util.java index 5ace632b..43aad67b 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Util.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Util.java @@ -720,26 +720,26 @@ public final class Util { if(playing) { Intent prevIntent = new Intent("KEYCODE_MEDIA_PREVIOUS"); prevIntent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); + prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS)); pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0); rv.setOnClickPendingIntent(R.id.control_previous, pendingIntent); } else { Intent prevIntent = new Intent("KEYCODE_MEDIA_STOP"); prevIntent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP)); + prevIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_STOP)); pendingIntent = PendingIntent.getService(context, 0, prevIntent, 0); rv.setOnClickPendingIntent(R.id.control_previous, pendingIntent); } Intent pauseIntent = new Intent("KEYCODE_MEDIA_PLAY_PAUSE"); pauseIntent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - pauseIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); + pauseIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)); pendingIntent = PendingIntent.getService(context, 0, pauseIntent, 0); rv.setOnClickPendingIntent(R.id.control_pause, pendingIntent); Intent nextIntent = new Intent("KEYCODE_MEDIA_NEXT"); nextIntent.setComponent(new ComponentName(context, DownloadServiceImpl.class)); - nextIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT)); + nextIntent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT)); pendingIntent = PendingIntent.getService(context, 0, nextIntent, 0); rv.setOnClickPendingIntent(R.id.control_next, pendingIntent); } |