v3.4.900
- Added playlist search
- Added Drive mode
- Added Album and Artist layout change option in library
- Added Show more album and artist information in details
- Added Pixel style scroller bar
- Added current now playing share
- Fix font issues and colors in some places
- Improved Full now playing theme
v3.4.850
- Added new theme called circle
- Added tiny color card style for home artists
- Added extra track info details to now playing themes
- Added scroll animation
- Added smooth transition animations 🤔
- Added current playing tab options for Bottom Navigation View
- Added search in genre
- Improved selecting feedback effect(ripple with corners)
- Fix bugs & crashes
- Fix crashing on lyrics
- Fix genre details last song is under mini player
- Fix colors mistakes and font sizes
- Fix slider jumping while scrolling in now playing themes
v3.4.800
- Improved dark theme colors and Follow system theme
- Rounded rectangle ripple for BottomNavigationView
- Follow sleep timer dialog checkbox color as accent
- Added song list selection for Album and Artist details
- Fixed Toolbar popup text color when selecting songs
v3.4.700
- Added splash screen(for app loading time)
- Updated dark theme colors
- Added circular progress view
- Hiding year if not showing
v3.4.600
- Fix notification layout height
- Fix folder list last item not showing
- Added auto hide/ show controls according to first and last item
v3.4.500
- Added peak theme
- Added app rating dialog
- Fix song name scrolling in now playing themes if it's long
- Fix playing queue last item hiding FAB
- Added desaturated color option for dark mode
- Fix slow search loading
- Fix last added slow loading
- Fix home banner toolbar corner
- Fix home crashing when switching between two tabs
- Fix remaining time in playing queue
- Fix font not applied for some components
- Fix crashing on album details sorting
- Fixed lot of internal bugs
- Fix dialog expand
- Fix list card color
- Removed SlidingUpPanel to replace with BottomSheet
- Removed color theme as per material design guidelines
- Removed classic theme(We're bringing back)
- Replace line switch to Material Switch in settings
- Performance improved
- Updated internal libraries
- Updated translation
- Limiting the use of Theme engine for making use of system colors
- Change home icon from the user icon
- Corrected all toolbar with elevation when scrolling
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
+
v3.4.950
- Added bluetooth connection to play on device as soon as it connected
- Fix tablet version of app
- Fix Album and Artist details toolbar full width for better accessibility
v3.4.900
- Added playlist search
- Added Drive mode
- Added Album and Artist layout change option in library
- Added Show more album and artist information in details
- Added Pixel style scroller bar
- Added current now playing share
- Fix font issues and colors in some places
- Improved Full now playing theme
v3.4.850
- Added new theme called circle
- Added tiny color card style for home artists
- Added extra track info details to now playing themes
- Added scroll animation
- Added smooth transition animations 🤔
- Added current playing tab options for Bottom Navigation View
- Added search in genre
- Improved selecting feedback effect(ripple with corners)
- Fix bugs & crashes
- Fix crashing on lyrics
- Fix genre details last song is under mini player
- Fix colors mistakes and font sizes
- Fix slider jumping while scrolling in now playing themes
v3.4.800
- Improved dark theme colors and Follow system theme
- Rounded rectangle ripple for BottomNavigationView
- Follow sleep timer dialog checkbox color as accent
- Added song list selection for Album and Artist details
- Fixed Toolbar popup text color when selecting songs
v3.4.700
- Added splash screen(for app loading time)
- Updated dark theme colors
- Added circular progress view
- Hiding year if not showing
v3.4.600
- Fix notification layout height
- Fix folder list last item not showing
- Added auto hide/ show controls according to first and last item
v3.4.500
- Added peak theme
- Added app rating dialog
- Fix song name scrolling in now playing themes if it's long
- Fix playing queue last item hiding FAB
- Added desaturated color option for dark mode
- Fix slow search loading
- Fix last added slow loading
- Fix home banner toolbar corner
- Fix home crashing when switching between two tabs
- Fix remaining time in playing queue
- Fix font not applied for some components
- Fix crashing on album details sorting
- Fixed lot of internal bugs
- Fix dialog expand
- Fix list card color
- Removed SlidingUpPanel to replace with BottomSheet
- Removed color theme as per material design guidelines
- Removed classic theme(We're bringing back)
- Replace line switch to Material Switch in settings
- Performance improved
- Updated internal libraries
- Updated translation
- Limiting the use of Theme engine for making use of system colors
- Change home icon from the user icon
- Corrected all toolbar with elevation when scrolling
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/activities/base/AbsMusicServiceActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
index 8472b51dc..a5c873092 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
@@ -149,7 +149,8 @@ abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventLis
override fun getPermissionsToRequest(): Array {
return arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.WRITE_EXTERNAL_STORAGE
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.BLUETOOTH
)
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt
index 83ab6fe1f..16e614b59 100644
--- a/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/preferences/AlbumCoverStylePreferenceDialog.kt
@@ -148,8 +148,8 @@ class AlbumCoverStylePreferenceDialog : PreferenceDialogFragmentCompat(), ViewPa
return values().size
}
- override fun isViewFromObject(view: View, `object`: Any): Boolean {
- return view === `object`
+ override fun isViewFromObject(view: View, instace: Any): Boolean {
+ return view === instace
}
override fun getPageTitle(position: Int): CharSequence? {
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 2d2f11164..37e7062a4 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
@@ -17,6 +17,7 @@ package code.name.monkey.retromusic.service;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
+import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -31,6 +32,8 @@ import android.media.AudioManager;
import android.media.audiofx.AudioEffect;
import android.os.Binder;
import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -218,6 +221,10 @@ public class MusicService extends Service implements
private boolean becomingNoisyReceiverRegistered;
+ private IntentFilter bluetoothConnectedIntentFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
+
+ private boolean bluetoothConnectedRegistered = false;
+
private IntentFilter headsetReceiverIntentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
private boolean headsetReceiverRegistered = false;
@@ -271,6 +278,27 @@ public class MusicService extends Service implements
private SongPlayCountHelper songPlayCountHelper = new SongPlayCountHelper();
+ private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ String action = intent.getAction();
+ Log.i(TAG, "onReceive: " + action);
+ if (action != null) {
+ if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
+ if (VERSION.SDK_INT >= VERSION_CODES.M) {
+ if (getAudioManager().getDevices(AudioManager.GET_DEVICES_OUTPUTS).length > 0) {
+ play();
+ }
+ } else {
+ if (getAudioManager().isBluetoothA2dpOn()) {
+ play();
+ }
+ }
+ }
+ }
+ }
+ };
+
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
@@ -299,11 +327,9 @@ public class MusicService extends Service implements
int state = intent.getIntExtra("state", -1);
switch (state) {
case 0:
- Log.d(TAG, "Headset unplugged");
pause();
break;
case 1:
- Log.d(TAG, "Headset plugged");
play();
break;
}
@@ -425,6 +451,7 @@ public class MusicService extends Service implements
sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"));
registerHeadsetEvents();
+ registerBluetoothConnected();
}
@Override
@@ -439,6 +466,10 @@ public class MusicService extends Service implements
unregisterReceiver(headsetReceiver);
headsetReceiverRegistered = false;
}
+ if (bluetoothConnectedRegistered) {
+ unregisterReceiver(bluetoothReceiver);
+ bluetoothConnectedRegistered = false;
+ }
mediaSession.setActive(false);
quit();
releaseResources();
@@ -1279,6 +1310,14 @@ public class MusicService extends Service implements
}
}
+ private void registerBluetoothConnected() {
+ Log.i(TAG, "registerBluetoothConnected: ");
+ if (!bluetoothConnectedRegistered) {
+ registerReceiver(bluetoothReceiver, bluetoothConnectedIntentFilter);
+ bluetoothConnectedRegistered = true;
+ }
+ }
+
private void registerHeadsetEvents() {
if (!headsetReceiverRegistered && PreferenceUtil.getInstance(this).getHeadsetPlugged()) {
registerReceiver(headsetReceiver, headsetReceiverIntentFilter);
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java b/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java
deleted file mode 100644
index 6f61630c1..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java
+++ /dev/null
@@ -1,370 +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.service;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.media.MediaDescription;
-import android.media.browse.MediaBrowser;
-import android.media.session.MediaSession;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.service.media.MediaBrowserService;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.helper.MusicPlayerRemote;
-import code.name.monkey.retromusic.loaders.AlbumLoader;
-import code.name.monkey.retromusic.loaders.ArtistLoader;
-import code.name.monkey.retromusic.loaders.PlaylistLoader;
-import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
-import code.name.monkey.retromusic.loaders.SongLoader;
-import code.name.monkey.retromusic.model.Album;
-import code.name.monkey.retromusic.model.Artist;
-import code.name.monkey.retromusic.model.Playlist;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.util.MusicUtil;
-import code.name.monkey.retromusic.util.RetroUtil;
-
-/**
- * @author Hemanth S (h4h13).
- */
-@TargetApi(21)
-public class WearBrowserService extends MediaBrowserService {
-
- public static final String MEDIA_ID_ROOT = "__ROOT__";
- public static final int TYPE_ARTIST = 0;
- public static final int TYPE_ALBUM = 1;
- public static final int TYPE_SONG = 2;
- public static final int TYPE_PLAYLIST = 3;
- public static final int TYPE_ARTIST_SONG_ALBUMS = 4;
- public static final int TYPE_ALBUM_SONGS = 5;
- public static final int TYPE_ARTIST_ALL_SONGS = 6;
- public static final int TYPE_PLAYLIST_ALL_SONGS = 7;
-
- public static WearBrowserService sInstance;
- private MediaSession mSession;
- private Context mContext;
- private boolean mServiceStarted;
-
- public static WearBrowserService getInstance() {
- return sInstance;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- sInstance = this;
- mContext = this;
- mSession = new MediaSession(this, "WearBrowserService");
- setSessionToken(mSession.getSessionToken());
- mSession.setCallback(new MediaSessionCallback());
- mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
- }
-
- @Override
- public int onStartCommand(Intent startIntent, int flags, int startId) {
- return START_STICKY;
- }
-
- @Override
- public void onDestroy() {
- mServiceStarted = false;
- mSession.release();
- }
-
- @Nullable
- @Override
- public BrowserRoot onGetRoot(@NonNull String s, int i, @Nullable Bundle bundle) {
- return new BrowserRoot(MEDIA_ID_ROOT, null);
- }
-
- @Override
- public void onLoadChildren(@NonNull String parentId, @NonNull Result> result) {
- result.detach();
- loadChildren(parentId, result);
- }
-
- private void setSessionActive() {
- if (!mServiceStarted) {
- startService(new Intent(getApplicationContext(), WearBrowserService.class));
- mServiceStarted = true;
- }
-
- if (!mSession.isActive()) {
- mSession.setActive(true);
- }
- }
-
- private void setSessionInactive() {
- if (mServiceStarted) {
- stopSelf();
- mServiceStarted = false;
- }
-
- if (mSession.isActive()) {
- mSession.setActive(false);
- }
- }
-
- private void fillMediaItems(List mediaItems,
- String mediaId,
- String title,
- String subTitle,
- Uri icon,
- int playableOrBrowsable) {
- mediaItems.add(new MediaBrowser.MediaItem(
- new MediaDescription.Builder()
- .setMediaId(mediaId)
- .setTitle(title)
- .setIconUri(icon)
- .setSubtitle(subTitle)
- .build(), playableOrBrowsable
- ));
- }
-
- private void addMediaRoots(List mMediaRoot) {
- mMediaRoot.add(new MediaBrowser.MediaItem(
- new MediaDescription.Builder()
- .setMediaId(Integer.toString(TYPE_ARTIST))
- .setTitle(getString(R.string.artists))
- .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_artist_art), 1f))
- .setSubtitle(getString(R.string.artists))
- .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
- ));
-
- mMediaRoot.add(new MediaBrowser.MediaItem(
- new MediaDescription.Builder()
- .setMediaId(Integer.toString(TYPE_ALBUM))
- .setTitle(getString(R.string.albums))
- .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f))
- .setSubtitle(getString(R.string.albums))
- .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
- ));
-
- mMediaRoot.add(new MediaBrowser.MediaItem(
- new MediaDescription.Builder()
- .setMediaId(Integer.toString(TYPE_SONG))
- .setTitle(getString(R.string.songs))
- .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f))
- .setSubtitle(getString(R.string.songs))
- .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
- ));
-
-
- mMediaRoot.add(new MediaBrowser.MediaItem(
- new MediaDescription.Builder()
- .setMediaId(Integer.toString(TYPE_PLAYLIST))
- .setTitle(getString(R.string.playlists))
- .setIconUri(Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp"))
- .setSubtitle(getString(R.string.playlists))
- .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE
- ));
-
- }
-
- private void loadChildren(final String parentId, final Result> result) {
-
- final List mediaItems = new ArrayList<>();
-
-
- new AsyncTask() {
- @Override
- protected Void doInBackground(final Void... unused) {
-
- if (parentId.equals(MEDIA_ID_ROOT)) {
- addMediaRoots(mediaItems);
- } else {
- switch (Integer.parseInt(Character.toString(parentId.charAt(0)))) {
- case TYPE_ARTIST:
- List artistList = ArtistLoader.INSTANCE.getAllArtists(mContext) ;
- for (Artist artist : artistList) {
- String albumNmber = String.format("%d %s", artist.getAlbums().size(), artist.getAlbums().size() > 1 ? "Albums" : "Album");
- String songCount = String.format("%d %s", artist.getSongs().size(), artist.getSongs().size() > 1 ? "Songs" : "Song");
- fillMediaItems(mediaItems,
- Integer.toString(TYPE_ARTIST_SONG_ALBUMS) + Long.toString(artist.getId()),
- artist.getName(),
- albumNmber + " • " + songCount,
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
- MediaBrowser.MediaItem.FLAG_BROWSABLE);
- }
- break;
-
- case TYPE_ARTIST_SONG_ALBUMS:
- fillMediaItems(mediaItems,
- Integer.toString(TYPE_ARTIST_ALL_SONGS) + Long.parseLong(parentId.substring(1)),
- "All songs",
- "All songs by artist",
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
- MediaBrowser.MediaItem.FLAG_BROWSABLE);
-
- List artistAlbums = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getAlbums(); //ArtistAlbumLoader.getAlbumsForArtist(mContext, Long.parseLong(parentId.substring(1)));
- for (Album album : artistAlbums) {
- String songCount = String.format("%d %s", album.getSongs().size(), album.getSongs().size() > 1 ? "Songs" : "Song");
- fillMediaItems(mediaItems,
- Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()),
- album.getTitle(),
- songCount,
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"),
- MediaBrowser.MediaItem.FLAG_BROWSABLE);
- }
- break;
- case TYPE_ALBUM:
- List albumList = AlbumLoader.INSTANCE.getAllAlbums(mContext);
- for (Album album : albumList) {
- fillMediaItems(mediaItems,
- Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()),
- album.getTitle(),
- album.getArtistName(),
- MusicUtil.getMediaStoreAlbumCoverUri(album.getId()),
- MediaBrowser.MediaItem.FLAG_BROWSABLE);
- }
- break;
- case TYPE_SONG:
- List songList = SongLoader.INSTANCE.getAllSongs(mContext);
- for (Song song : songList) {
- fillMediaItems(mediaItems,
- String.valueOf(song.getId()),
- song.getTitle(),
- song.getAlbumName(),
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
- MediaBrowser.MediaItem.FLAG_PLAYABLE);
- }
- break;
-
- case TYPE_ALBUM_SONGS:
- List albumSongList = AlbumLoader.INSTANCE.getAlbum(mContext, Integer.parseInt(parentId.substring(1))).getSongs();
- for (Song song : albumSongList) {
- fillMediaItems(mediaItems,
- String.valueOf(song.getId()),
- song.getTitle(),
- song.getAlbumName(),
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
- MediaBrowser.MediaItem.FLAG_PLAYABLE);
- }
- break;
- case TYPE_ARTIST_ALL_SONGS:
- List artistSongs = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getSongs();
- for (Song song : artistSongs) {
- fillMediaItems(mediaItems,
- String.valueOf(song.getId()),
- song.getTitle(),
- song.getAlbumName(),
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
- MediaBrowser.MediaItem.FLAG_PLAYABLE);
- }
- break;
- case TYPE_PLAYLIST:
- List playlistList = PlaylistLoader.INSTANCE.getAllPlaylists(mContext);
- for (Playlist playlist : playlistList) {
- int size = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, playlist).size();
- String songCount = String.format("%d %s", size, size > 1 ? "Songs" : "Song");
- fillMediaItems(mediaItems,
- Integer.toString(TYPE_PLAYLIST_ALL_SONGS) + Long.toString(playlist.id),
- playlist.name,
- songCount,
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp"),
- MediaBrowser.MediaItem.FLAG_BROWSABLE);
- }
- break;
- case TYPE_PLAYLIST_ALL_SONGS:
- List playlistSongs = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, Integer.parseInt(parentId.substring(1)));
- for (Song song : playlistSongs) {
- fillMediaItems(mediaItems,
- String.valueOf(song.getId()),
- song.getTitle(),
- song.getAlbumName(),
- Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"),
- MediaBrowser.MediaItem.FLAG_PLAYABLE);
- }
- break;
-
- }
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void aVoid) {
- result.sendResult(mediaItems);
- }
- }.execute();
-
- }
-
- private final class MediaSessionCallback extends MediaSession.Callback {
-
- @Override
- public void onPlay() {
- setSessionActive();
- }
-
- @Override
- public void onSeekTo(long position) {
-
- }
-
- @Override
- public void onPlayFromMediaId(final String mediaId, Bundle extras) {
- long songId = Long.parseLong(mediaId);
- setSessionActive();
- ArrayList songs = new ArrayList<>();
- songs.add(SongLoader.INSTANCE.getSong(mContext, Integer.parseInt(mediaId)));
- MusicPlayerRemote.INSTANCE.openQueue(songs, 0, true);
- }
-
- @Override
- public void onPause() {
-
- }
-
- @Override
- public void onStop() {
- setSessionInactive();
- }
-
- @Override
- public void onSkipToNext() {
-
- }
-
- @Override
- public void onSkipToPrevious() {
-
- }
-
- @Override
- public void onFastForward() {
-
- }
-
- @Override
- public void onRewind() {
-
- }
-
- @Override
- public void onCustomAction(@NonNull String action, Bundle extras) {
-
- }
- }
-}