diff --git a/app/build.gradle b/app/build.gradle index f0171d5a..cdb432bf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,7 +23,7 @@ android { applicationId "code.name.monkey.retromusic" versionCode 409 - versionName '3.5.000' + versionName '3.4.950' multiDexEnabled true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a73fb094..888def0e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,19 +3,20 @@ xmlns:tools="http://schemas.android.com/tools" package="code.name.monkey.retromusic"> + + -

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 8472b51d..a5c87309 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 83ab6fe1..16e614b5 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 2d2f1116..37e7062a 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 6f61630c..00000000 --- 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) { - - } - } -}