diff --git a/app/build.gradle b/app/build.gradle
index 104a8f9a..5ac7feed 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -13,7 +13,7 @@ android {
vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic"
- versionCode 352
+ versionCode 353
versionName '3.3.100'
multiDexEnabled true
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4f39ddd1..5dfe9e91 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
@@ -252,30 +247,30 @@
+ android:resource="@xml/automotive_app_desc"/>
+ android:resource="@drawable/ic_notification"/>
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/assets/retro-changelog.html b/app/src/main/assets/retro-changelog.html
index cf09b953..3cc479cf 100644
--- a/app/src/main/assets/retro-changelog.html
+++ b/app/src/main/assets/retro-changelog.html
@@ -1 +1 @@
-
v3.3.000
- SD card support for deleting and editing
v3.2.240
- Improved options dialog with selected color and title icon
- Fix dialog color on dark theme
v3.2.220
- Fix Notification SeekBar position (Need Android Q test)
- Rolled back settings tint icons
- Changed preference category title style according Android Q
- Fix tabs options not working
v3.2.203
- Carousel effect improved
- Settings icons are now tint accent color
- Settings title, back arrow and icons are now tint accent color
- Equalizer is removed
- Fix keyboard not popping on Search
- Curated the main options
- Folder toolbar outlined, folder icon background fix and separate line removed
- Edit text input handles are colored
v3.2.135
- Fix crashing on sharing song
v3.2.125
- Fix crashing on selecting profile picture
- Semi transparent color fix(s) on now playing themes
v3.2.120
- Fix crashing on choosing a theme
- Fix color theme selection without pro enabled
- Fix icon tint some places
v3.2.105
v3.2.100
- Fix crashing on Sleep timer
- Toolbar elevation removed added stroke instead
- Show empty indication for home
v3.2.000
- Implemented Artist image loading all thanks to VinylMusicPlayer
- Fixed buttons in Genre details
- Fixed color buttons in Album and Artist details screen
v3.1.900
- Added Play and Shuffle buttons on Songs list, Album Details, Artist Details, Playlist
Details etc.
- Home toolbar is semi transparent in Banner mode
- Added new Buy Retro Music pro in settings
- Improved dark color in Dark theme
v3.1.850
- Toolbar will be clickable for Search
v3.1.800
- Search bar CardView background
- Improve volume zero
- Now playing and Album theme picker rollback to dialog
- Fix sharing app link
- Fix scanning dialog
- Added settings icons for options
v3.1.700
- Cleaned internal code
- Removed full screen option
- Added Toolbar elevation
- To access menu either tap on Toolbar or Hamburger icon
- Fix back button not working on playing queue
- Fix crashing on What's New screen
- Fix lyrics dialog
- Changed toggles to line icons
- Custom UserImageView for loading user profile image
- Fix crashing on artist list for number format error
- Fix blacklist dialog crashing
- Rearranged icons and main menu access
- Fix some crashes when device is locked or background
- Folder screen have main options access
- Dialogs are now using Material Dialogs v3(BottomSheet)
- Fix Shuffle icon for Artist, Album, Genre and Playlist details
v3.1.400
- Removed sync lyrics for Android 5
- Fix Seek-bar color in settings
- Added keyboard to popup on search
- Added keyboard to popup on search
- Improved lock-screen behavior and UI
- Improved text appearance
- Fix bio text not showing in settings
- Fix not showing slider(blur, filter song) amount in settings
- Fix setting ringtone
- Fix file sharing crash
- Fix some crashes
- Fix playlist icon on small devices
- Fix empty lyrics text color
- Fix album cover background purple color in color theme
v3.1.300
- Fix rename playlist text color
- Fix same album showing in details page
- Fix lyrics text alignment on sync and lyrics reading improved
- Improved home sections loading
- Removed library options which are duplicated (it's available from profile menu)
- Replaced collapsing Fab with Android Floating Extended Fab
- Replaced home with for you
- Fixed profile image not loading in about
- Improved selecting user profile image
- Added bio to enter custom message
- Improved some UI screens
v3.1.240
- Fix Search not showing from home screen
- Fix Volume controls color issue
- Fix Seek bar alignment
- Added tiny theme
- Improved full theme appearances
- Now playing theme preview updated
- Fix composer error
- Bottom Options improved(internal)
v3.1.200
- Added composer sort and editing
- Fix Crash in Album tag editor while selecting options
- Added Filter song length
- Added Favourites playlist icon will be accent color
- Added Colorful settings icons
- Added Corners for dialog
v3.0.570
- Fix Album/Artist square image
- Fix Delete dialog text format
- Fix Profile picture not showing after coming back from folders
- Fix Play button color i Simple and Plain themes
- Fix Sleep timer dialog crashing
- Fix Share song dialog title and text
If you see entire app white or dark or black select same theme in settings to fix
FAQ's
*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again.
\ No newline at end of file
+
v.3.3.100
- Improved Now playing controls alignment
- Lot internal changes to improve performance
- Fix playlist adding crash
- Fix color corrections
- Fix file editing crash
v3.3.000
- SD card support for deleting and editing
v3.2.240
- Improved options dialog with selected color and title icon
- Fix dialog color on dark theme
v3.2.220
- Fix Notification SeekBar position (Need Android Q test)
- Rolled back settings tint icons
- Changed preference category title style according Android Q
- Fix tabs options not working
v3.2.203
- Carousel effect improved
- Settings icons are now tint accent color
- Settings title, back arrow and icons are now tint accent color
- Equalizer is removed
- Fix keyboard not popping on Search
- Curated the main options
- Folder toolbar outlined, folder icon background fix and separate line removed
- Edit text input handles are colored
v3.2.135
- Fix crashing on sharing song
v3.2.125
- Fix crashing on selecting profile picture
- Semi transparent color fix(s) on now playing themes
v3.2.120
- Fix crashing on choosing a theme
- Fix color theme selection without pro enabled
- Fix icon tint some places
v3.2.105
v3.2.100
- Fix crashing on Sleep timer
- Toolbar elevation removed added stroke instead
- Show empty indication for home
v3.2.000
- Implemented Artist image loading all thanks to VinylMusicPlayer
- Fixed buttons in Genre details
- Fixed color buttons in Album and Artist details screen
v3.1.900
- Added Play and Shuffle buttons on Songs list, Album Details, Artist Details, Playlist
Details etc.
- Home toolbar is semi transparent in Banner mode
- Added new Buy Retro Music pro in settings
- Improved dark color in Dark theme
v3.1.850
- Toolbar will be clickable for Search
v3.1.800
- Search bar CardView background
- Improve volume zero
- Now playing and Album theme picker rollback to dialog
- Fix sharing app link
- Fix scanning dialog
- Added settings icons for options
v3.1.700
- Cleaned internal code
- Removed full screen option
- Added Toolbar elevation
- To access menu either tap on Toolbar or Hamburger icon
- Fix back button not working on playing queue
- Fix crashing on What's New screen
- Fix lyrics dialog
- Changed toggles to line icons
- Custom UserImageView for loading user profile image
- Fix crashing on artist list for number format error
- Fix blacklist dialog crashing
- Rearranged icons and main menu access
- Fix some crashes when device is locked or background
- Folder screen have main options access
- Dialogs are now using Material Dialogs v3(BottomSheet)
- Fix Shuffle icon for Artist, Album, Genre and Playlist details
v3.1.400
- Removed sync lyrics for Android 5
- Fix Seek-bar color in settings
- Added keyboard to popup on search
- Added keyboard to popup on search
- Improved lock-screen behavior and UI
- Improved text appearance
- Fix bio text not showing in settings
- Fix not showing slider(blur, filter song) amount in settings
- Fix setting ringtone
- Fix file sharing crash
- Fix some crashes
- Fix playlist icon on small devices
- Fix empty lyrics text color
- Fix album cover background purple color in color theme
v3.1.300
- Fix rename playlist text color
- Fix same album showing in details page
- Fix lyrics text alignment on sync and lyrics reading improved
- Improved home sections loading
- Removed library options which are duplicated (it's available from profile menu)
- Replaced collapsing Fab with Android Floating Extended Fab
- Replaced home with for you
- Fixed profile image not loading in about
- Improved selecting user profile image
- Added bio to enter custom message
- Improved some UI screens
v3.1.240
- Fix Search not showing from home screen
- Fix Volume controls color issue
- Fix Seek bar alignment
- Added tiny theme
- Improved full theme appearances
- Now playing theme preview updated
- Fix composer error
- Bottom Options improved(internal)
v3.1.200
- Added composer sort and editing
- Fix Crash in Album tag editor while selecting options
- Added Filter song length
- Added Favourites playlist icon will be accent color
- Added Colorful settings icons
- Added Corners for dialog
v3.0.570
- Fix Album/Artist square image
- Fix Delete dialog text format
- Fix Profile picture not showing after coming back from folders
- Fix Play button color i Simple and Plain themes
- Fix Sleep timer dialog crashing
- Fix Share song dialog title and text
If you see entire app white or dark or black select same theme in settings to fix
FAQ's
*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again.
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java
index 35858c76..563dd743 100644
--- a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java
+++ b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMediaIDHelper.java
@@ -30,6 +30,7 @@ public class AutoMediaIDHelper {
public static final String MEDIA_ID_MUSICS_BY_PLAYLIST = "__BY_PLAYLIST__";
public static final String MEDIA_ID_MUSICS_BY_ALBUM = "__BY_ALBUM__";
public static final String MEDIA_ID_MUSICS_BY_ARTIST = "__BY_ARTIST__";
+ public static final String MEDIA_ID_MUSICS_BY_GENRE = "__BY_GENRE__";
public static final String MEDIA_ID_MUSICS_BY_SHUFFLE = "__BY_SHUFFLE__";
public static final String MEDIA_ID_MUSICS_BY_QUEUE = "__BY_QUEUE__";
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.java b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.java
index 77cae609..ea13395c 100644
--- a/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.java
+++ b/app/src/main/java/code/name/monkey/retromusic/auto/AutoMusicProvider.java
@@ -32,19 +32,19 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
-import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.loaders.AlbumLoader;
import code.name.monkey.retromusic.loaders.ArtistLoader;
+import code.name.monkey.retromusic.loaders.GenreLoader;
import code.name.monkey.retromusic.loaders.PlaylistLoader;
import code.name.monkey.retromusic.loaders.TopAndRecentlyPlayedTracksLoader;
import code.name.monkey.retromusic.model.Album;
import code.name.monkey.retromusic.model.Artist;
+import code.name.monkey.retromusic.model.Genre;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.providers.MusicPlaybackQueueStore;
import code.name.monkey.retromusic.service.MusicService;
-import code.name.monkey.retromusic.util.ImageUtil;
/**
* Created by Beesham Sarendranauth (Beesham)
@@ -57,7 +57,10 @@ public class AutoMusicProvider {
private static final int PATH_SEGMENT_ID = 0;
private static final int PATH_SEGMENT_TITLE = 1;
private static final int PATH_SEGMENT_ARTIST = 2;
+ private static final int PATH_SEGMENT_GENRE = 4;
+ private static final int PATH_SEGMENT_ALBUM_ID = 5;
+ private WeakReference mMusicService;
// Categorized caches for music data
private ConcurrentMap mMusicListByHistory;
@@ -65,6 +68,7 @@ public class AutoMusicProvider {
private ConcurrentMap mMusicListByPlaylist;
private ConcurrentMap mMusicListByAlbum;
private ConcurrentMap mMusicListByArtist;
+ private ConcurrentMap mMusicListByGenre;
private Uri defaultAlbumArtUri;
@@ -79,12 +83,17 @@ public class AutoMusicProvider {
mMusicListByPlaylist = new ConcurrentSkipListMap<>();
mMusicListByAlbum = new ConcurrentSkipListMap<>();
mMusicListByArtist = new ConcurrentSkipListMap<>();
+ mMusicListByGenre = new ConcurrentSkipListMap<>();
defaultAlbumArtUri = Uri.parse("android.resource://" +
mContext.getPackageName() + "/drawable/" +
mContext.getResources().getResourceEntryName(R.drawable.default_album_art));
}
+ public void setMusicService(MusicService service) {
+ mMusicService = new WeakReference<>(service);
+ }
+
public Iterable getHistory() {
if (mCurrentState != State.INITIALIZED) {
return Collections.emptyList();
@@ -120,6 +129,13 @@ public class AutoMusicProvider {
return mMusicListByArtist.values();
}
+ public Iterable getGenres() {
+ if (mCurrentState != State.INITIALIZED) {
+ return Collections.emptyList();
+ }
+ return mMusicListByGenre.values();
+ }
+
public Iterable getQueue() {
if (mCurrentState != State.INITIALIZED) {
return Collections.emptyList();
@@ -128,8 +144,9 @@ public class AutoMusicProvider {
// Re-built every time since the queue updates often
ConcurrentMap queueList = new ConcurrentSkipListMap<>();
- if (mContext != null) {
- final List songs = MusicPlaybackQueueStore.getInstance(mContext).getSavedOriginalPlayingQueue();
+ final MusicService service = mMusicService.get();
+ if (service != null) {
+ final List songs = MusicPlaybackQueueStore.getInstance(service).getSavedOriginalPlayingQueue();
for (int i = 0; i < songs.size(); i++) {
final Song s = songs.get(i);
Uri.Builder topTracksData = Uri.parse(BASE_URI).buildUpon();
@@ -260,6 +277,21 @@ public class AutoMusicProvider {
mMusicListByArtist = newMusicListByArtist;
}
+ private synchronized void buildListsByGenre() {
+ ConcurrentMap newMusicListByGenre = new ConcurrentSkipListMap<>();
+
+ final List genres = GenreLoader.INSTANCE.getAllGenres(mContext);
+ for (int i = 0; i < genres.size(); i++) {
+ final Genre p = genres.get(i);
+ Uri.Builder playlistData = Uri.parse(BASE_URI).buildUpon();
+ playlistData.appendPath(String.valueOf(p.getId()))
+ .appendPath(p.getName());
+ newMusicListByGenre.putIfAbsent(i, playlistData.build());
+ }
+
+ mMusicListByGenre = newMusicListByGenre;
+ }
+
private synchronized void retrieveMedia() {
try {
if (mCurrentState == State.NON_INITIALIZED) {
@@ -270,6 +302,7 @@ public class AutoMusicProvider {
buildListsByPlaylist();
buildListsByAlbum();
buildListsByArtist();
+ buildListsByGenre();
mCurrentState = State.INITIALIZED;
}
} finally {
@@ -290,13 +323,31 @@ public class AutoMusicProvider {
switch (mediaId) {
case AutoMediaIDHelper.MEDIA_ID_ROOT:
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY, resources.getString(R.string.history_label), R.drawable.ic_access_time_white_24dp));
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_TOP_TRACKS, resources.getString(R.string.top_tracks_label), R.drawable.ic_trending_up_white_24dp));
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST, resources.getString(R.string.playlists_label), R.drawable.ic_queue_music_white_24dp));
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM, resources.getString(R.string.albums_label), R.drawable.ic_album_white_24dp));
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ARTIST, resources.getString(R.string.artists_label), R.drawable.ic_artist_white_24dp));
- mediaItems.add(createPlayableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_SHUFFLE, resources.getString(R.string.action_shuffle_all), R.drawable.ic_shuffle_white_24dp, null));
- mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE, resources.getString(R.string.queue_label), R.drawable.ic_playlist_play_white_24dp));
+ //mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY, resources.getString(R.string.history_label), R.drawable.ic_access_time_white_24dp));
+ //mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_TOP_TRACKS, resources.getString(R.string.top_tracks_label), R.drawable.ic_trending_up_white_24dp));
+ //mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST, resources.getString(R.string.playlists_label), R.drawable.ic_queue_music_white_24dp));
+ mediaItems.add(
+ createBrowsableMediaItem(
+ AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM,
+ resources.getString(R.string.albums_label),
+ R.drawable.ic_album_white_24dp));
+ mediaItems.add(
+ createBrowsableMediaItem(
+ AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_ARTIST,
+ resources.getString(R.string.artists_label),
+ R.drawable.ic_artist_white_24dp));
+ mediaItems.add(
+ createBrowsableMediaItem(
+ AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE,
+ resources.getString(R.string.genres_label),
+ R.drawable.ic_guitar_acoustic_white_24dp));
+ mediaItems.add(
+ createPlayableMediaItem(
+ AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_SHUFFLE,
+ resources.getString(R.string.action_shuffle_all),
+ R.drawable.ic_shuffle_white_24dp,
+ ""));
+ //mediaItems.add(createBrowsableMediaItem(AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE, resources.getString(R.string.queue_label), R.drawable.ic_playlist_play_white_24dp));
break;
case AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY:
@@ -328,6 +379,11 @@ public class AutoMusicProvider {
mediaItems.add(createPlayableMediaItem(mediaId, uri, uri.getPathSegments().get(PATH_SEGMENT_ARTIST), null));
}
break;
+ case AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE:
+ for (final Uri uri : getGenres()) {
+ mediaItems.add(createPlayableMediaItem(mediaId, uri, uri.getPathSegments().get(PATH_SEGMENT_TITLE), null));
+ }
+ break;
case AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE:
// TODO: auto scroll to current track, indicate that it's playing
@@ -343,21 +399,25 @@ public class AutoMusicProvider {
private MediaBrowserCompat.MediaItem createBrowsableMediaItem(String mediaId, String title, int iconDrawableId) {
MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder();
builder.setMediaId(mediaId)
- .setTitle(title)
- .setIconBitmap(ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(mContext, iconDrawableId, ThemeStore.Companion.textColorSecondary(mContext))));
+ .setTitle(title);
return new MediaBrowserCompat.MediaItem(builder.build(),
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
}
- private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId, Uri musicSelection,
- String title, @Nullable String subtitle) {
+ private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId,
+ Uri musicSelection,
+ String title,
+ @Nullable String subtitle) {
return createPlayableMediaItem(mediaId, musicSelection, title, subtitle, null, null);
}
- private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId, Uri musicSelection,
- String title, @Nullable String subtitle,
- @Nullable Bitmap albumArt, @Nullable Resources resources) {
+ private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId,
+ Uri musicSelection,
+ String title,
+ @Nullable String subtitle,
+ @Nullable Bitmap albumArt,
+ @Nullable Resources resources) {
MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder();
builder.setMediaId(AutoMediaIDHelper.createMediaID(musicSelection.getPathSegments().get(PATH_SEGMENT_ID), mediaId))
.setTitle(title);
@@ -378,12 +438,13 @@ public class AutoMusicProvider {
MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
}
- private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId, String title, int iconDrawableId,
+ private MediaBrowserCompat.MediaItem createPlayableMediaItem(String mediaId,
+ String title,
+ int iconDrawableId,
@Nullable String subtitle) {
MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder()
.setMediaId(mediaId)
- .setTitle(title)
- .setIconBitmap(ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(mContext, iconDrawableId, ThemeStore.Companion.textColorSecondary(mContext))));
+ .setTitle(title);
if (subtitle != null) {
builder.setSubtitle(subtitle);
diff --git a/app/src/main/java/code/name/monkey/retromusic/auto/CarHelper.java b/app/src/main/java/code/name/monkey/retromusic/auto/CarHelper.java
deleted file mode 100644
index 9c6ebd36..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/auto/CarHelper.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This 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 software 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.
- */
-package code.name.monkey.retromusic.auto;
-
-import android.app.UiModeManager;
-import android.content.Context;
-import android.content.res.Configuration;
-
-public class CarHelper {
-
- private static final String TAG = "CarHelper";
-
- public static boolean isCarUiMode(Context c) {
- UiModeManager uiModeManager = (UiModeManager) c.getSystemService(Context.UI_MODE_SERVICE);
- return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MediaSessionCallback.kt b/app/src/main/java/code/name/monkey/retromusic/service/MediaSessionCallback.kt
index dfa91487..06642b9c 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/MediaSessionCallback.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/service/MediaSessionCallback.kt
@@ -92,6 +92,10 @@ class MediaSessionCallback(private val context: Context,
songs.addAll(playlist.getSongs(context))
openQueue(songs, 0, true)
}
+ AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE -> {
+ songs.addAll(GenreLoader.getSongs(context, itemId))
+ openQueue(songs, 0, true)
+ }
AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_HISTORY,
AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_TOP_TRACKS,
AutoMediaIDHelper.MEDIA_ID_MUSICS_BY_QUEUE -> {
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
index c9234377..b5913c34 100644
--- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
+++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
@@ -337,8 +337,10 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this);
restoreState();
+
mPackageValidator = new PackageValidator(this, R.xml.allowed_media_browser_callers);
mMusicProvider = new AutoMusicProvider(this);
+
sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"));
registerHeadsetEvents();
@@ -352,19 +354,26 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
}
private void setupMediaSession() {
- ComponentName mediaButtonReceiverComponentName = new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class);
+ ComponentName mediaButtonReceiverComponentName = new ComponentName(
+ getApplicationContext(),
+ MediaButtonIntentReceiver.class);
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(mediaButtonReceiverComponentName);
- PendingIntent mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
+ PendingIntent mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(
+ getApplicationContext(),
+ 0,
+ mediaButtonIntent,
+ 0);
mediaSession = new MediaSessionCompat(this,
"RetroMusicPlayer",
mediaButtonReceiverComponentName,
mediaButtonReceiverPendingIntent);
- MediaSessionCallback mediasessionCallback = new MediaSessionCallback(getApplicationContext(), this);
+ MediaSessionCallback mediasessionCallback = new MediaSessionCallback(
+ getApplicationContext(), this);
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
);
@@ -418,7 +427,7 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
}
}
- return START_STICKY;
+ return START_NOT_STICKY;
}
private void playFromPlaylist(Intent intent) {
@@ -445,21 +454,6 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
}
}
- private void playSongs(int shuffleMode, ArrayList playlistSongs) {
- if (!playlistSongs.isEmpty()) {
- if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
- int startPosition;
- startPosition = new Random().nextInt(playlistSongs.size());
- openQueue(playlistSongs, startPosition, true);
- setShuffleMode(shuffleMode);
- } else {
- openQueue(playlistSongs, 0, true);
- }
- } else {
- Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show();
- }
- }
-
@Override
public void onDestroy() {
unregisterReceiver(widgetIntentReceiver);
@@ -478,20 +472,28 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this);
wakeLock.release();
- sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_MUSIC_SERVICE_DESTROYED"));
+ sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_DESTROYED"));
}
@Override
public IBinder onBind(Intent intent) {
+ // For Android auto, need to call super, or onGetRoot won't be called.
+ if (intent != null && "android.media.browse.MediaBrowserService".equals(intent.getAction())) {
+ return super.onBind(intent);
+ }
return musicBind;
}
@Nullable
@Override
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) {
+
+ // Check origin to ensure we're not allowing any arbitrary app to browse app contents
if (!mPackageValidator.isKnownCaller(clientPackageName, clientUid)) {
+ // Request from an untrusted package: return an empty browser root
return new BrowserRoot(AutoMediaIDHelper.MEDIA_ID_EMPTY_ROOT, null);
}
+
return new BrowserRoot(AutoMediaIDHelper.MEDIA_ID_ROOT, null);
}
@@ -686,10 +688,33 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
.setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
getSongProgressMillis(), 1);
+ setCustomAction(stateBuilder);
mediaSession.setPlaybackState(stateBuilder.build());
}
+ private void setCustomAction(PlaybackStateCompat.Builder stateBuilder) {
+ int repeatIcon = R.drawable.ic_repeat_white_24dp; // REPEAT_MODE_NONE
+ if (getRepeatMode() == REPEAT_MODE_THIS) {
+ repeatIcon = R.drawable.ic_repeat_one_white_24dp;
+ } else if (getRepeatMode() == REPEAT_MODE_ALL) {
+ repeatIcon = R.drawable.ic_repeat_white_24dp;
+ }
+ stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
+ CYCLE_REPEAT, getString(R.string.action_cycle_repeat), repeatIcon)
+ .build());
+
+ final int shuffleIcon = getShuffleMode() == SHUFFLE_MODE_NONE ? R.drawable.ic_shuffle_white_24dp : R.drawable.ic_shuffle_white_24dp;
+ stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
+ TOGGLE_SHUFFLE, getString(R.string.action_toggle_shuffle), shuffleIcon)
+ .build());
+
+ final int favoriteIcon = MusicUtil.isFavorite(getApplicationContext(), getCurrentSong()) ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_favorite_border_white_24dp;
+ stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
+ TOGGLE_FAVORITE, getString(R.string.action_toggle_favorite), favoriteIcon)
+ .build());
+ }
+
private void updateMediaSessionMetaData() {
final Song song = getCurrentSong();
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt b/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
index d6df60ad..d75bd28b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
@@ -11,8 +11,10 @@
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
+
package code.name.monkey.retromusic.util
+
import android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE
import android.Manifest.permission.MEDIA_CONTENT_CONTROL
import android.annotation.SuppressLint
@@ -45,7 +47,10 @@ import java.security.NoSuchAlgorithmException
*
* For more information, see res/xml/allowed_media_browser_callers.xml.
*/
-class PackageValidator(context: Context, @XmlRes xmlResId: Int) {
+class PackageValidator(
+ context: Context,
+ @XmlRes xmlResId: Int
+) {
private val context: Context
private val packageManager: PackageManager
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d571c0fb..a89c9027 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -191,6 +191,7 @@
Genre
Genres
+ Genres
Fork the project on GitHub
diff --git a/app/src/main/res/xml/allowed_media_browser_callers.xml b/app/src/main/res/xml/allowed_media_browser_callers.xml
index a8861593..2fa94b88 100644
--- a/app/src/main/res/xml/allowed_media_browser_callers.xml
+++ b/app/src/main/res/xml/allowed_media_browser_callers.xml
@@ -1,12 +1,9 @@
@@ -164,32 +160,6 @@ limitations under the License.
BKZCvlzboOEAZfx8aBKc7SezqATXpM3ZDNPsywWoyIpgmtBWoE60ih4Flf05XB+n
e7MdpSQ0Xgq9TgG1BoJP6rpC0y3Ukmc+z8AXnYYdJunNXEbv0A==
-
- MIIDvTCCAqWgAwIBAgIJAMePnkuTQTAGMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
- BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
- aWV3MRQwEgYDVQQKDAtHb29nbGUgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDERMA8G
- A1UEAwwIZ2VhcmhlYWQwHhcNMTQwNTI3MjMwNTM0WhcNNDExMDEyMjMwNTM0WjB1
- MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
- bnRhaW4gVmlldzEUMBIGA1UECgwLR29vZ2xlIEluYy4xEDAOBgNVBAsMB0FuZHJv
- aWQxETAPBgNVBAMMCGdlYXJoZWFkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
- CgKCAQEA050XDkNIsVRMX2wTvVplpCu4OtnyNK2v5B7PS+DggmH2yuZiwpTurdKD
- Q9R9UzxH9U4lsC+mIxXkiBYKIWNVgMtiTgxkEy7cgWvdYHgNYpFu8IxZKYDyXes+
- 02pfvpu63MIBD/PnvVFipo1oUrbfetj+mroEpjnA71gUS0Ok+H6XWWsmb8xFHQVM
- oZWEIzsUJ2nhm8EcnPkAPfNZAG++XLPROoRQCaswyYsd42JuYAP3CwZuhDcUbMWm
- k7rBi9BVQ8gmkrbwqo94A7qStLUp3NyCmlKSWHaZ05SspEPwsfctka0oXG5bhgT6
- 67EMCzQ+YsFN1oJRL7Qq+mMQjFJs3wIDAQABo1AwTjAdBgNVHQ4EFgQUGvBfYNeu
- 6JSJUnJZCiaBGsnXztswHwYDVR0jBBgwFoAUGvBfYNeu6JSJUnJZCiaBGsnXztsw
- DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAlGsDY0EPu3NBSH5k6iw/
- wJh9e3xMwS17ErKGlhyWogxJMzLjAN6g0aCPHxB40IQC+8qAl+RL7VQx6oxttf0m
- 31yUGQPcNYbt2CxBTCAr885oLK5t2TAi5tQzhd6ZEYihWSUWUd/X8BQRouxboss9
- QbBA/iIx0OpDaxiAcq7Cb67TheXZDxGuQ8fmHYbLx84pEvm3DQOB/LIMkkpQSfEC
- 1f+oP1zB3urPU/dSvED/LCgOdrpxZ5di7SwSyue+Vq/TZQy34tPygEzD2d8hFlh/
- yfhWkMizOeIXcayVAQdNn5zpBkuay1skGOjQQ5kTbDcDzigO2R2rqn6HCd9l5Z0W
- IQ==
-
-
- MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYD
- VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
- VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
- AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
- Fw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzET
- MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
- A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
- ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
- hvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR
- 24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVy
- xW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8X
- W8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC
- 69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexA
- cKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkw
- HQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0c
- xb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
- CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
- QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
- CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1Ud
- EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrP
- zgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXcla
- XjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05a
- IskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+a
- ayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUW
- Ev9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
-
- MIIDvTCCAqWgAwIBAgIJAMePnkuTQTAGMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV
- BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
- aWV3MRQwEgYDVQQKDAtHb29nbGUgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDERMA8G
- A1UEAwwIZ2VhcmhlYWQwHhcNMTQwNTI3MjMwNTM0WhcNNDExMDEyMjMwNTM0WjB1
- MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
- bnRhaW4gVmlldzEUMBIGA1UECgwLR29vZ2xlIEluYy4xEDAOBgNVBAsMB0FuZHJv
- aWQxETAPBgNVBAMMCGdlYXJoZWFkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
- CgKCAQEA050XDkNIsVRMX2wTvVplpCu4OtnyNK2v5B7PS+DggmH2yuZiwpTurdKD
- Q9R9UzxH9U4lsC+mIxXkiBYKIWNVgMtiTgxkEy7cgWvdYHgNYpFu8IxZKYDyXes+
- 02pfvpu63MIBD/PnvVFipo1oUrbfetj+mroEpjnA71gUS0Ok+H6XWWsmb8xFHQVM
- oZWEIzsUJ2nhm8EcnPkAPfNZAG++XLPROoRQCaswyYsd42JuYAP3CwZuhDcUbMWm
- k7rBi9BVQ8gmkrbwqo94A7qStLUp3NyCmlKSWHaZ05SspEPwsfctka0oXG5bhgT6
- 67EMCzQ+YsFN1oJRL7Qq+mMQjFJs3wIDAQABo1AwTjAdBgNVHQ4EFgQUGvBfYNeu
- 6JSJUnJZCiaBGsnXztswHwYDVR0jBBgwFoAUGvBfYNeu6JSJUnJZCiaBGsnXztsw
- DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAlGsDY0EPu3NBSH5k6iw/
- wJh9e3xMwS17ErKGlhyWogxJMzLjAN6g0aCPHxB40IQC+8qAl+RL7VQx6oxttf0m
- 31yUGQPcNYbt2CxBTCAr885oLK5t2TAi5tQzhd6ZEYihWSUWUd/X8BQRouxboss9
- QbBA/iIx0OpDaxiAcq7Cb67TheXZDxGuQ8fmHYbLx84pEvm3DQOB/LIMkkpQSfEC
- 1f+oP1zB3urPU/dSvED/LCgOdrpxZ5di7SwSyue+Vq/TZQy34tPygEzD2d8hFlh/
- yfhWkMizOeIXcayVAQdNn5zpBkuay1skGOjQQ5kTbDcDzigO2R2rqn6HCd9l5Z0W
- IQ==
+ MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNV
+ BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBW
+ aWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4G
+ A1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQx
+ CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3Vu
+ dGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9p
+ ZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
+ ggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JO
+ Rland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/
+ 8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfY
+ wXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LW
+ uT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0z
+ OHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Yl
+ mn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14al
+ oXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
+ BxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsT
+ B0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTAD
+ AQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4
+ rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCE
+ yj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh
+ 5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTb
+ Qe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZM
+ cUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
\ No newline at end of file