From f03fe63ecd8603575b5e0ab8f9f8b6f6b3821f5b Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Sat, 23 Apr 2016 14:46:56 -0700 Subject: #170 Add Variable Playback Speed --- app/build.gradle | 15 +++---- .../dsub/fragments/NowPlayingFragment.java | 46 +++++++++++++++++++++ .../daneren2005/dsub/service/DownloadService.java | 32 +++++++++++++- .../github/daneren2005/dsub/util/Constants.java | 1 + .../ic_action_playback_speed_dark.png | Bin 0 -> 1008 bytes .../ic_action_playback_speed_light.png | Bin 0 -> 1229 bytes .../ic_action_playback_speed_dark.png | Bin 0 -> 625 bytes .../ic_action_playback_speed_light.png | Bin 0 -> 739 bytes .../ic_action_playback_speed_dark.png | Bin 0 -> 1429 bytes .../ic_action_playback_speed_light.png | Bin 0 -> 1689 bytes .../ic_action_playback_speed_dark.png | Bin 0 -> 2377 bytes .../ic_action_playback_speed_light.png | Bin 0 -> 2793 bytes .../ic_action_playback_speed_dark.png | Bin 0 -> 3618 bytes .../ic_action_playback_speed_light.png | Bin 0 -> 4334 bytes app/src/main/res/layout-land/download.xml | 5 +++ app/src/main/res/layout-large-land/download.xml | 5 +++ app/src/main/res/layout-port/download.xml | 5 +++ app/src/main/res/menu/playback_speed_options.xml | 22 ++++++++++ app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/strings.xml | 5 +++ app/src/main/res/values/themes.xml | 2 + 21 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png create mode 100644 app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png create mode 100644 app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png create mode 100644 app/src/main/res/menu/playback_speed_options.xml diff --git a/app/build.gradle b/app/build.gradle index e8b7108a..2cf18f0e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,9 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 22 - buildToolsVersion "22.0.0" + compileSdkVersion 23 + buildToolsVersion "23.0.3" + useLibrary 'org.apache.http.legacy' defaultConfig { applicationId "github.daneren2005.dsub" @@ -42,11 +43,11 @@ android { dependencies { compile project(':Server Proxy') compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:support-v4:22.2.+' - compile 'com.android.support:appcompat-v7:22.2.+' - compile 'com.android.support:mediarouter-v7:22.2.+' - compile 'com.android.support:recyclerview-v7:22.2.+' - compile 'com.android.support:design:22.2.+' + compile 'com.android.support:support-v4:23.3.+' + compile 'com.android.support:appcompat-v7:23.3.+' + compile 'com.android.support:mediarouter-v7:23.3.+' + compile 'com.android.support:recyclerview-v7:23.3.+' + compile 'com.android.support:design:23.3.+' compile 'com.google.android.gms:play-services-cast:8.1.0' compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'de.hdodenhof:circleimageview:1.2.1' diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java index c8e99f51..e4984fce 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java @@ -51,6 +51,7 @@ import android.view.animation.AnimationUtils; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.PopupMenu; import android.widget.SeekBar; import android.widget.TextView; import android.widget.ViewFlipper; @@ -116,6 +117,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis private ImageButton bookmarkButton; private ImageButton rateBadButton; private ImageButton rateGoodButton; + private ImageButton playbackSpeedButton; private ScheduledExecutorService executorService; private DownloadFile currentPlaying; @@ -182,6 +184,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis bookmarkButton = (ImageButton) rootView.findViewById(R.id.download_bookmark); rateBadButton = (ImageButton) rootView.findViewById(R.id.download_rating_bad); rateGoodButton = (ImageButton) rootView.findViewById(R.id.download_rating_good); + playbackSpeedButton = (ImageButton) rootView.findViewById(R.id.download_playback_speed); toggleListButton =rootView.findViewById(R.id.download_toggle_list); playlistView = (RecyclerView)rootView.findViewById(R.id.download_list); @@ -216,6 +219,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis bookmarkButton.setOnTouchListener(touchListener); rateBadButton.setOnTouchListener(touchListener); rateGoodButton.setOnTouchListener(touchListener); + playbackSpeedButton.setOnTouchListener(touchListener); emptyTextView.setOnTouchListener(touchListener); albumArtImageView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -386,6 +390,48 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis } }); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + playbackSpeedButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(context, v); + popup.getMenuInflater().inflate(R.menu.playback_speed_options, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + DownloadService downloadService = getDownloadService(); + if (downloadService == null) { + return false; + } + + float playbackSpeed = 1.0f; + switch (menuItem.getItemId()) { + case R.id.playback_speed_half: + playbackSpeed = 0.5f; + break; + case R.id.playback_speed_one_half: + playbackSpeed = 1.5f; + break; + case R.id.playback_speed_double: + playbackSpeed = 2.0f; + break; + case R.id.playback_speed_tripple: + playbackSpeed = 3.0f; + break; + } + + downloadService.setPlaybackSpeed(playbackSpeed); + return true; + } + }); + popup.show(); + } + }); + } else { + playbackSpeedButton.setVisibility(View.GONE); + } + toggleListButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java index 01007b68..988dea5f 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java @@ -76,6 +76,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; import android.media.MediaPlayer; +import android.media.PlaybackParams; import android.media.audiofx.AudioEffect; import android.net.wifi.WifiManager; import android.os.Build; @@ -161,6 +162,7 @@ public class DownloadService extends Service { private int cachedPosition = 0; private boolean downloadOngoing = false; private float volume = 1.0f; + private long delayUpdateProgress = 1000L; private AudioEffectsController effectsController; private RemoteControlState remoteState = LOCAL; @@ -1503,7 +1505,7 @@ public class DownloadService extends Service { while(isRunning) { try { onSongProgress(); - Thread.sleep(1000L); + Thread.sleep(delayUpdateProgress); } catch(Exception e) { isRunning = false; @@ -1545,7 +1547,7 @@ public class DownloadService extends Service { } } onSongProgress(cachedPosition < 2000 ? true: false); - Thread.sleep(1000L); + Thread.sleep(delayUpdateProgress); } catch(Exception e) { Log.w(TAG, "Crashed getting current position", e); @@ -1877,6 +1879,7 @@ public class DownloadService extends Service { cachedPosition = position; applyReplayGain(mediaPlayer, downloadFile); + applyPlaybackParams(mediaPlayer); if (start || autoPlayStart) { mediaPlayer.start(); @@ -1947,6 +1950,7 @@ public class DownloadService extends Service { } applyReplayGain(nextMediaPlayer, downloadFile); + applyPlaybackParams(nextMediaPlayer); } catch (Exception x) { handleErrorNext(x); } @@ -2600,6 +2604,30 @@ public class DownloadService extends Service { } } + public void setPlaybackSpeed(float playbackSpeed) { + Util.getPreferences(this).edit().putFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, playbackSpeed).commit(); + applyPlaybackParams(mediaPlayer); + if(nextMediaPlayer != null && nextPlayerState == PREPARED) { + applyPlaybackParams(nextMediaPlayer); + } + + delayUpdateProgress = Math.round(1000L / playbackSpeed); + } + public float getPlaybackSpeed() { + return Util.getPreferences(this).getFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, 1.0f); + } + private synchronized void applyPlaybackParams(MediaPlayer mediaPlayer) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + float playbackSpeed = getPlaybackSpeed(); + + if(playbackSpeed != 1.0f || mediaPlayer.getPlaybackParams() != null) { + PlaybackParams playbackParams = new PlaybackParams(); + playbackParams.setSpeed(playbackSpeed); + mediaPlayer.setPlaybackParams(playbackParams); + } + } + } + public void toggleStarred() { final DownloadFile currentPlaying = this.currentPlaying; if(currentPlaying == null) { diff --git a/app/src/main/java/github/daneren2005/dsub/util/Constants.java b/app/src/main/java/github/daneren2005/dsub/util/Constants.java index ec3489ab..230cce16 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/Constants.java +++ b/app/src/main/java/github/daneren2005/dsub/util/Constants.java @@ -174,6 +174,7 @@ public final class Constants { public static final String PREFERENCES_KEY_CAST_STREAM_ORIGINAL = "castStreamOriginal"; public static final String PREFERENCES_KEY_HEADS_UP_NOTIFICATION = "headsUpNotification"; public static final String PREFERENCES_KEY_CAST_CACHE = "castCache"; + public static final String PREFERENCES_KEY_PLAYBACK_SPEED = "playbackSpeed"; public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount"; public static final String OFFLINE_SCROBBLE_ID = "scrobbleID"; diff --git a/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png new file mode 100644 index 00000000..5f4d890a Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png new file mode 100644 index 00000000..4b481822 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png new file mode 100644 index 00000000..b05ecefd Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png new file mode 100644 index 00000000..392d2b4d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png new file mode 100644 index 00000000..2aeadf7e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png new file mode 100644 index 00000000..ce3f561c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png new file mode 100644 index 00000000..a9acc5e6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png new file mode 100644 index 00000000..dcd6fea8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png new file mode 100644 index 00000000..c1e92342 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png new file mode 100644 index 00000000..3dc5f32a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png differ diff --git a/app/src/main/res/layout-land/download.xml b/app/src/main/res/layout-land/download.xml index 9451a587..1bae4ae2 100644 --- a/app/src/main/res/layout-land/download.xml +++ b/app/src/main/res/layout-land/download.xml @@ -64,6 +64,11 @@ style="@style/DownloadActionImageButton" android:src="@android:drawable/star_big_off"/> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 2d3794d6..7cd447f0 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -42,6 +42,7 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4b3dc1c9..896f3dac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -220,6 +220,11 @@ Thumbs Up Thumbs Down Batch Mode + 0.5x + 1.0x + 1.5x + 2.0x + 3.0x New podcasts available New songs in playlists diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e86084b0..9e95fe9d 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -43,6 +43,7 @@ @drawable/ic_menu_radio_dark @drawable/ic_toggle_star_outline_light @drawable/ic_menu_download_dark + @drawable/ic_action_playback_speed_light @drawable/main_offline_light @drawable/ic_menu_library_light @drawable/ic_menu_playlist_light @@ -113,6 +114,7 @@ @drawable/ic_menu_radio_dark @drawable/ic_toggle_star_outline_dark @drawable/ic_menu_download_dark + @drawable/ic_action_playback_speed_dark @drawable/main_offline_dark @drawable/ic_menu_library_dark @drawable/ic_menu_playlist_dark -- cgit v1.2.3 From 54e52d3cd7624c3053d0c83e87799a1388731cbb Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Wed, 4 May 2016 21:34:54 -0700 Subject: #170 Only keep variable playback speed during same album --- .../daneren2005/dsub/service/DownloadService.java | 38 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java index f1cebaef..98e678c1 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java @@ -106,6 +106,7 @@ public class DownloadService extends Service { public static final String START_PLAY = "github.daneren2005.dsub.START_PLAYING"; public static final int FAST_FORWARD = 30000; public static final int REWIND = 10000; + private static final long DEFAULT_DELAY_UPDATE_PROGRESS = 1000L; private static final double DELETE_CUTOFF = 0.84; private static final int REQUIRED_ALBUM_MATCHES = 4; private static final int REMOTE_PLAYLIST_TOTAL = 3; @@ -162,7 +163,7 @@ public class DownloadService extends Service { private int cachedPosition = 0; private boolean downloadOngoing = false; private float volume = 1.0f; - private long delayUpdateProgress = 1000L; + private long delayUpdateProgress = DEFAULT_DELAY_UPDATE_PROGRESS; private AudioEffectsController effectsController; private RemoteControlState remoteState = LOCAL; @@ -854,6 +855,9 @@ public class DownloadService extends Service { if(this.currentPlaying != null) { this.currentPlaying.setPlaying(false); } + if(delayUpdateProgress != DEFAULT_DELAY_UPDATE_PROGRESS && !isNextPlayingSameAlbum(currentPlaying, this.currentPlaying)) { + resetPlaybackSpeed(); + } this.currentPlaying = currentPlaying; if(currentPlaying == null) { currentPlayingIndex = -1; @@ -1953,7 +1957,7 @@ public class DownloadService extends Service { } applyReplayGain(nextMediaPlayer, downloadFile); - applyPlaybackParams(nextMediaPlayer); + applyPlaybackParamsNext(); } catch (Exception x) { handleErrorNext(x); } @@ -2609,16 +2613,40 @@ public class DownloadService extends Service { public void setPlaybackSpeed(float playbackSpeed) { Util.getPreferences(this).edit().putFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, playbackSpeed).commit(); - applyPlaybackParams(mediaPlayer); + applyPlaybackParamsMain(); if(nextMediaPlayer != null && nextPlayerState == PREPARED) { - applyPlaybackParams(nextMediaPlayer); + applyPlaybackParamsNext(); } - delayUpdateProgress = Math.round(1000L / playbackSpeed); + delayUpdateProgress = Math.round(DEFAULT_DELAY_UPDATE_PROGRESS / playbackSpeed); } + private void resetPlaybackSpeed() { + Util.getPreferences(this).edit().remove(Constants.PREFERENCES_KEY_PLAYBACK_SPEED).commit(); + } + public float getPlaybackSpeed() { return Util.getPreferences(this).getFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, 1.0f); } + + private synchronized void applyPlaybackParamsMain() { + applyPlaybackParams(mediaPlayer); + } + private synchronized void applyPlaybackParamsNext() { + if(isNextPlayingSameAlbum()) { + applyPlaybackParams(nextMediaPlayer); + } + } + private synchronized boolean isNextPlayingSameAlbum() { + return isNextPlayingSameAlbum(currentPlaying, nextPlaying); + } + private synchronized boolean isNextPlayingSameAlbum(DownloadFile currentPlaying, DownloadFile nextPlaying) { + if(currentPlaying == null || nextPlaying == null) { + return false; + } else { + return currentPlaying.getSong().getAlbum().equals(nextPlaying.getSong().getAlbum()); + } + } + private synchronized void applyPlaybackParams(MediaPlayer mediaPlayer) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { float playbackSpeed = getPlaybackSpeed(); -- cgit v1.2.3 From a351831caceb87c5da5599c8ad5eb633ea4d8264 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Wed, 4 May 2016 21:37:34 -0700 Subject: #170 Don't show variable speed when casting --- .../github/daneren2005/dsub/fragments/NowPlayingFragment.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java index e4984fce..3831a4c0 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java @@ -511,7 +511,8 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis } boolean equalizerAvailable = downloadService != null && downloadService.getEqualizerAvailable(); - if(equalizerAvailable && !downloadService.isRemoteEnabled()) { + boolean isRemoteEnabled = downloadService != null && downloadService.isRemoteEnabled(); + if(equalizerAvailable && !isRemoteEnabled) { SharedPreferences prefs = Util.getPreferences(context); boolean equalizerOn = prefs.getBoolean(Constants.PREFERENCES_EQUALIZER_ON, false); if (equalizerOn && downloadService != null) { @@ -523,6 +524,12 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis menu.removeItem(R.id.menu_equalizer); } + if(isRemoteEnabled) { + playbackSpeedButton.setVisibility(View.GONE); + } else { + playbackSpeedButton.setVisibility(View.VISIBLE); + } + if(downloadService != null) { MenuItem mediaRouteItem = menu.findItem(R.id.menu_mediaroute); if(mediaRouteItem != null) { -- cgit v1.2.3 From 403a0b8e6d0d45ffda1c32baa89c187876fa53ef Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Wed, 4 May 2016 21:56:38 -0700 Subject: #170 Add status indicator for playback speed --- .../dsub/fragments/NowPlayingFragment.java | 26 +++++++++++++++++++++- app/src/main/res/values/strings.xml | 6 ++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java index 3831a4c0..87ccbd64 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java @@ -422,6 +422,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis } downloadService.setPlaybackSpeed(playbackSpeed); + updateTitle(); return true; } }); @@ -524,7 +525,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis menu.removeItem(R.id.menu_equalizer); } - if(isRemoteEnabled) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isRemoteEnabled) { playbackSpeedButton.setVisibility(View.GONE); } else { playbackSpeedButton.setVisibility(View.VISIBLE); @@ -794,6 +795,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis downloadService.addOnSongChangedListener(NowPlayingFragment.this, true); } updateRepeatButton(); + updateTitle(); } }); } @@ -1255,6 +1257,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis rewindButton.setVisibility(View.GONE); fastforwardButton.setVisibility(View.GONE); } + updateTitle(); } private void setupSubtitle(int currentPlayingIndex) { @@ -1465,6 +1468,27 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis break; } } + private void updateTitle() { + DownloadService downloadService = getDownloadService(); + float playbackSpeed = downloadService.getPlaybackSpeed(); + + String title = context.getResources().getString(R.string.button_bar_now_playing); + int stringRes = -1; + if(playbackSpeed == 0.5f) { + stringRes = R.string.download_playback_speed_half; + } else if(playbackSpeed == 1.5f) { + stringRes = R.string.download_playback_speed_one_half; + } else if(playbackSpeed == 2.0f) { + stringRes = R.string.download_playback_speed_double; + } else if(playbackSpeed == 3.0f) { + stringRes = R.string.download_playback_speed_tripple; + } + + if(stringRes != -1) { + title += " (" + context.getResources().getString(stringRes) + ")"; + } + setTitle(title); + } @Override protected List getSelectedEntries() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 896f3dac..6837a88b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -221,10 +221,10 @@ Thumbs Down Batch Mode 0.5x - 1.0x + 1x 1.5x - 2.0x - 3.0x + 2x + 3x New podcasts available New songs in playlists -- cgit v1.2.3 From 21806c87a6290e731b314ade5809424217dd4c31 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Mon, 30 May 2016 16:33:22 -0500 Subject: Upgrade to latest support lib --- app/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ec714e76..584f10f3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,11 +43,11 @@ android { dependencies { compile project(':Server Proxy') compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:support-v4:23.3.+' - compile 'com.android.support:appcompat-v7:23.3.+' - compile 'com.android.support:mediarouter-v7:23.3.+' - compile 'com.android.support:recyclerview-v7:23.3.+' - compile 'com.android.support:design:23.3.+' + compile 'com.android.support:support-v4:23.4.+' + compile 'com.android.support:appcompat-v7:23.4.+' + compile 'com.android.support:mediarouter-v7:23.4.+' + compile 'com.android.support:recyclerview-v7:23.4.+' + compile 'com.android.support:design:23.4.+' compile 'com.google.android.gms:play-services-cast:8.1.0' compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'de.hdodenhof:circleimageview:1.2.1' -- cgit v1.2.3 From 6e4258781771be4735fe482218e2fec7194fbd9b Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Mon, 25 Jul 2016 17:35:19 -0700 Subject: Fix dropdown color on newer versions of support lib --- .../github/daneren2005/dsub/activity/SubsonicActivity.java | 2 +- .../main/java/github/daneren2005/dsub/util/DrawableTint.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java index 06559456..9f73f865 100644 --- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java +++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java @@ -192,7 +192,7 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte protected void createCustomActionBarView() { actionBarSpinner = (Spinner) getLayoutInflater().inflate(R.layout.actionbar_spinner, null); if((this instanceof SubsonicFragmentActivity || this instanceof SettingsActivity) && (Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true) || Util.getThemeRes(this) != R.style.Theme_DSub_Light_No_Color)) { - actionBarSpinner.setBackgroundResource(R.drawable.abc_spinner_mtrl_am_alpha); + actionBarSpinner.setBackgroundDrawable(DrawableTint.getTintedDrawableFromColor(this, R.drawable.abc_spinner_mtrl_am_alpha, android.R.color.white)); } spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); diff --git a/app/src/main/java/github/daneren2005/dsub/util/DrawableTint.java b/app/src/main/java/github/daneren2005/dsub/util/DrawableTint.java index 2da72579..cc8e241d 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/DrawableTint.java +++ b/app/src/main/java/github/daneren2005/dsub/util/DrawableTint.java @@ -21,6 +21,7 @@ import android.content.res.TypedArray; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.support.annotation.AttrRes; +import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.util.TypedValue; @@ -48,6 +49,17 @@ public class DrawableTint { tintedDrawables.put(drawableRes, background); return background; } + public static Drawable getTintedDrawableFromColor(Context context, @DrawableRes int drawableRes, @ColorRes int colorRes) { + if(tintedDrawables.containsKey(drawableRes)) { + return tintedDrawables.get(drawableRes); + } + + int color = context.getResources().getColor(colorRes); + Drawable background = context.getResources().getDrawable(drawableRes); + background.setColorFilter(color, PorterDuff.Mode.SRC_IN); + tintedDrawables.put(drawableRes, background); + return background; + } public static int getColorRes(Context context, @AttrRes int colorAttr) { int color; if(attrMap.containsKey(colorAttr)) { -- cgit v1.2.3 From 48ea6cd175f4e620c668ce94c2b1a0e3e2c906c6 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Tue, 26 Jul 2016 17:21:43 -0700 Subject: Fix being able to add albums to playlists --- .../java/github/daneren2005/dsub/fragments/SubsonicFragment.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java index 9cc27128..ab3db50f 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java @@ -1008,6 +1008,14 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR } protected void addToPlaylist(final List songs) { + Iterator it = songs.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + if(entry.isDirectory()) { + it.remove(); + } + } + if(songs.isEmpty()) { Util.toast(context, "No songs selected"); return; -- cgit v1.2.3 From aeb5cf0c40a177e6a4ecfbbf0f4e059618311242 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Tue, 26 Jul 2016 22:01:03 -0700 Subject: Fix the cast dialog theme not matching --- .../daneren2005/dsub/fragments/NowPlayingFragment.java | 3 ++- .../compat/CustomMediaRouteChooserDialogFragment.java | 15 +++++++++++++++ .../CustomMediaRouteControllerDialogFragment.java | 15 +++++++++++++++ .../dsub/view/compat/CustomMediaRouteDialogFactory.java | 17 +++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteChooserDialogFragment.java create mode 100644 app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteControllerDialogFragment.java create mode 100644 app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteDialogFactory.java diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java index 530c03b6..7c20dc28 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java @@ -60,7 +60,6 @@ import github.daneren2005.dsub.activity.SubsonicFragmentActivity; import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.audiofx.EqualizerController; import github.daneren2005.dsub.domain.Bookmark; -import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.PlayerState; import github.daneren2005.dsub.domain.RepeatMode; import github.daneren2005.dsub.domain.ServerInfo; @@ -74,6 +73,7 @@ import github.daneren2005.dsub.service.ServerTooOldException; import github.daneren2005.dsub.util.Constants; import github.daneren2005.dsub.util.SilentBackgroundTask; import github.daneren2005.dsub.adapter.DownloadFileAdapter; +import github.daneren2005.dsub.view.compat.CustomMediaRouteDialogFactory; import github.daneren2005.dsub.view.FadeOutAnimation; import github.daneren2005.dsub.view.FastScroller; import github.daneren2005.dsub.view.UpdateView; @@ -535,6 +535,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis MenuItem mediaRouteItem = menu.findItem(R.id.menu_mediaroute); if(mediaRouteItem != null) { MediaRouteButton mediaRouteButton = (MediaRouteButton) MenuItemCompat.getActionView(mediaRouteItem); + mediaRouteButton.setDialogFactory(new CustomMediaRouteDialogFactory()); mediaRouteButton.setRouteSelector(downloadService.getRemoteSelector()); } } diff --git a/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteChooserDialogFragment.java b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteChooserDialogFragment.java new file mode 100644 index 00000000..da9b135f --- /dev/null +++ b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteChooserDialogFragment.java @@ -0,0 +1,15 @@ +package github.daneren2005.dsub.view.compat; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.app.MediaRouteChooserDialog; +import android.support.v7.app.MediaRouteChooserDialogFragment; + +import github.daneren2005.dsub.util.Util; + +public class CustomMediaRouteChooserDialogFragment extends MediaRouteChooserDialogFragment { + @Override + public MediaRouteChooserDialog onCreateChooserDialog(Context context, Bundle savedInstanceState) { + return new MediaRouteChooserDialog(context, Util.getThemeRes(context)); + } +} diff --git a/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteControllerDialogFragment.java b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteControllerDialogFragment.java new file mode 100644 index 00000000..7fd54142 --- /dev/null +++ b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteControllerDialogFragment.java @@ -0,0 +1,15 @@ +package github.daneren2005.dsub.view.compat; + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.app.MediaRouteControllerDialog; +import android.support.v7.app.MediaRouteControllerDialogFragment; + +import github.daneren2005.dsub.util.Util; + +public class CustomMediaRouteControllerDialogFragment extends MediaRouteControllerDialogFragment { + @Override + public MediaRouteControllerDialog onCreateControllerDialog(Context context, Bundle savedInstanceState) { + return new MediaRouteControllerDialog(context, Util.getThemeRes(context)); + } +} diff --git a/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteDialogFactory.java b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteDialogFactory.java new file mode 100644 index 00000000..8bc890cb --- /dev/null +++ b/app/src/main/java/github/daneren2005/dsub/view/compat/CustomMediaRouteDialogFactory.java @@ -0,0 +1,17 @@ +package github.daneren2005.dsub.view.compat; + +import android.support.v7.app.MediaRouteChooserDialogFragment; +import android.support.v7.app.MediaRouteControllerDialogFragment; +import android.support.v7.app.MediaRouteDialogFactory; + +public class CustomMediaRouteDialogFactory extends MediaRouteDialogFactory { + @Override + public MediaRouteChooserDialogFragment onCreateChooserDialogFragment() { + return new CustomMediaRouteChooserDialogFragment(); + } + + @Override + public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { + return new CustomMediaRouteControllerDialogFragment(); + } +} -- cgit v1.2.3