Added room for now playing queue

main
h4h13 2020-04-25 12:57:05 +05:30
parent 6cdaf27eda
commit 2da9d1c5b7
14 changed files with 211 additions and 25 deletions

View File

@ -184,4 +184,9 @@ dependencies {
def dagger_version = "2.23.1"
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
}

View File

@ -76,7 +76,7 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
playingQueueAdapter = PlayingQueueAdapter(
this,
MusicPlayerRemote.playingQueue,
MusicPlayerRemote.playingQueue.toMutableList(),
MusicPlayerRemote.position,
R.layout.item_queue
)

View File

@ -16,11 +16,10 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import java.util.*
class AlbumCoverPagerAdapter(
fragmentManager: FragmentManager,
private val dataSet: ArrayList<Song>
private val dataSet: List<Song>
) : CustomFragmentStatePagerAdapter(fragmentManager) {
private var currentColorReceiver: AlbumCoverFragment.ColorReceiver? = null
@ -95,7 +94,8 @@ class AlbumCoverPagerAdapter(
savedInstanceState: Bundle?
): View? {
val finalLayout = when {
PreferenceUtil.getInstance(requireContext()).carouselEffect() -> R.layout.fragment_album_carousel_cover
PreferenceUtil.getInstance(requireContext())
.carouselEffect() -> R.layout.fragment_album_carousel_cover
else -> layout
}
val view = inflater.inflate(finalLayout, container, false)

View File

@ -23,11 +23,10 @@ import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAct
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
import com.h6ah4i.android.widget.advrecyclerview.swipeable.annotation.SwipeableItemResults
import me.zhanghai.android.fastscroll.PopupTextProvider
import java.util.*
class PlayingQueueAdapter(
activity: AppCompatActivity,
dataSet: ArrayList<Song>,
dataSet: MutableList<Song>,
private var current: Int,
itemLayoutRes: Int
) : SongAdapter(
@ -82,8 +81,8 @@ class PlayingQueueAdapter(
// We don't want to load it in this adapter
}
fun swapDataSet(dataSet: ArrayList<Song>, position: Int) {
this.dataSet = dataSet
fun swapDataSet(dataSet: List<Song>, position: Int) {
this.dataSet = dataSet.toMutableList()
current = position
notifyDataSetChanged()
}

View File

@ -86,7 +86,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(),
return true
}
R.id.action_save_playing_queue -> {
CreatePlaylistDialog.create(MusicPlayerRemote.playingQueue)
CreatePlaylistDialog.create(ArrayList(MusicPlayerRemote.playingQueue))
.show(childFragmentManager, "ADD_TO_PLAYLIST")
return true
}

View File

@ -79,7 +79,7 @@ class PlayingQueueFragment :
override fun createAdapter(): PlayingQueueAdapter {
return PlayingQueueAdapter(
requireActivity() as AppCompatActivity,
MusicPlayerRemote.playingQueue,
MusicPlayerRemote.playingQueue.toMutableList(),
MusicPlayerRemote.position,
R.layout.item_queue
)

View File

@ -37,6 +37,7 @@ object MusicPlayerRemote {
val TAG: String = MusicPlayerRemote::class.java.simpleName
private val mConnectionMap = WeakHashMap<Context, ServiceBinder>()
var musicService: MusicService? = null
@JvmStatic
val isPlaying: Boolean
get() = musicService != null && musicService!!.isPlaying
@ -64,11 +65,12 @@ object MusicPlayerRemote {
musicService!!.position = position
}
}
@JvmStatic
val playingQueue: ArrayList<Song>
val playingQueue: List<Song>
get() = if (musicService != null) {
musicService?.playingQueue as ArrayList<Song>
} else ArrayList()
musicService?.playingQueue as List<Song>
} else listOf<Song>()
val songProgressMillis: Int
get() = if (musicService != null) {
@ -84,6 +86,7 @@ object MusicPlayerRemote {
get() = if (musicService != null) {
musicService!!.repeatMode
} else MusicService.REPEAT_MODE_NONE
@JvmStatic
val shuffleMode: Int
get() = if (musicService != null) {
@ -456,7 +459,8 @@ object MusicPlayerRemote {
@TargetApi(Build.VERSION_CODES.KITKAT)
private fun getSongIdFromMediaProvider(uri: Uri): String {
return DocumentsContract.getDocumentId(uri).split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
return DocumentsContract.getDocumentId(uri).split(":".toRegex())
.dropLastWhile { it.isEmpty() }.toTypedArray()[1]
}
class ServiceBinder internal constructor(private val mCallback: ServiceConnection?) :

View File

@ -14,6 +14,7 @@
package code.name.monkey.retromusic.model
import android.os.Parcelable
import code.name.monkey.retromusic.room.SongEntity
import kotlinx.android.parcel.Parcelize
@Parcelize
@ -34,6 +35,23 @@ open class Song(
companion object {
fun toSongEntity(song: Song): SongEntity {
return SongEntity(
song.id,
song.title,
song.trackNumber,
song.year,
song.duration,
song.data,
song.dateModified,
song.albumId,
song.albumName,
song.artistId,
song.artistName,
song.composer
)
}
@JvmStatic
val emptySong = Song(
-1,

View File

@ -0,0 +1,34 @@
package code.name.monkey.retromusic.room
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [SongEntity::class], version = 2, exportSchema = false)
abstract class MusicPlaybackQueueStoreDatabase : RoomDatabase() {
abstract fun queueDao(): QueueDao
companion object {
@Volatile
private var INSTANCE: MusicPlaybackQueueStoreDatabase? = null
fun getMusicDatabase(context: Context): MusicPlaybackQueueStoreDatabase {
val tempInstance =
INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
MusicPlaybackQueueStoreDatabase::class.java,
"music_playback_state"
).fallbackToDestructiveMigration().build()
INSTANCE = instance
return instance
}
}
}
}

View File

@ -0,0 +1,16 @@
package code.name.monkey.retromusic.room
class MusicQueueRepository(private val queueDao: QueueDao) {
fun getQueue(): List<SongEntity> = queueDao.getQueue()
fun getOriginalQueue(): List<SongEntity> = queueDao.getQueue()
suspend fun insertQueue(queue: List<SongEntity>) {
queueDao.saveQueue(queue)
}
suspend fun insertOriginalQueue(queue: List<SongEntity>) {
queueDao.saveQueue(queue)
}
}

View File

@ -0,0 +1,42 @@
package code.name.monkey.retromusic.room
import android.content.Context
import code.name.monkey.retromusic.model.Song
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class NowPlayingQueue(context: Context) {
private val queueDao = MusicPlaybackQueueStoreDatabase.getMusicDatabase(context).queueDao()
private val musicQueueRepository: MusicQueueRepository = MusicQueueRepository(queueDao)
fun saveQueue(songs: List<Song>) = GlobalScope.launch(Dispatchers.IO) {
val songEntity = songs.map {
Song.toSongEntity(it)
}
musicQueueRepository.insertQueue(songEntity)
}
fun saveOriginalQueue(playingQueue: List<Song>) = GlobalScope.launch(Dispatchers.IO) {
val songEntity = playingQueue.map {
Song.toSongEntity(it)
}
musicQueueRepository.insertOriginalQueue(songEntity)
}
fun getQueue(): List<Song> {
val songEntity = musicQueueRepository.getQueue()
return songEntity.map {
SongEntity.toSong(it)
}
}
fun getOriginalQueue(): List<Song> {
val songEntity = musicQueueRepository.getOriginalQueue()
return songEntity.map {
SongEntity.toSong(it)
}
}
}

View File

@ -0,0 +1,23 @@
package code.name.monkey.retromusic.room
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
/**
* Created by hemanths on 2020-02-23.
*/
@Dao
interface QueueDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun saveQueue(playingQueue: List<SongEntity>)
@Query("SELECT * FROM song_entity")
fun getQueue(): List<SongEntity>
@Query("SELECT * FROM song_entity")
fun getOriginalQueue(): List<SongEntity>
}

View File

@ -0,0 +1,41 @@
package code.name.monkey.retromusic.room
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import code.name.monkey.retromusic.model.Song
@Entity(tableName = "song_entity")
class SongEntity(
@PrimaryKey val id: Int,
@ColumnInfo(name = "title") val title: String,
@ColumnInfo(name = "track_number") val trackNumber: Int,
@ColumnInfo(name = "year") val year: Int,
@ColumnInfo(name = "duration") val duration: Long,
@ColumnInfo(name = "data") val data: String,
@ColumnInfo(name = "date_modified") val dateModified: Long,
@ColumnInfo(name = "album_id") val albumId: Int,
@ColumnInfo(name = "album_name") val albumName: String,
@ColumnInfo(name = "artist_id") val artistId: Int,
@ColumnInfo(name = "artist_name") val artistName: String,
@ColumnInfo(name = "composer") val composer: String?
) {
companion object {
fun toSong(song: SongEntity): Song {
return Song(
song.id,
song.title,
song.trackNumber,
song.year,
song.duration,
song.data,
song.dateModified,
song.albumId,
song.albumName,
song.artistId,
song.artistName,
song.composer
)
}
}
}

View File

@ -74,8 +74,8 @@ import code.name.monkey.retromusic.helper.ShuffleHelper;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.providers.HistoryStore;
import code.name.monkey.retromusic.providers.MusicPlaybackQueueStore;
import code.name.monkey.retromusic.providers.SongPlayCountStore;
import code.name.monkey.retromusic.room.NowPlayingQueue;
import code.name.monkey.retromusic.service.notification.PlayingNotification;
import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl;
import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo;
@ -206,11 +206,9 @@ public class MusicService extends Service implements
private MediaSessionCompat mediaSession;
private ContentObserver mediaStoreObserver;
private HandlerThread musicPlayerHandlerThread;
private boolean notHandledMetaChangedForCurrentTrack;
private ArrayList<Song> originalPlayingQueue = new ArrayList<>();
private List<Song> originalPlayingQueue = new ArrayList<>();
private List<Song> playingQueue = new ArrayList<>();
private boolean pausedByTransientLossOfFocus;
private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
@ -239,7 +237,7 @@ public class MusicService extends Service implements
updateNotification();
}
};
private ArrayList<Song> playingQueue = new ArrayList<>();
private QueueSaveHandler queueSaveHandler;
private HandlerThread queueSaveHandlerThread;
private boolean queuesRestored;
@ -306,6 +304,7 @@ public class MusicService extends Service implements
private ThrottledSeekHandler throttledSeekHandler;
private Handler uiThreadHandler;
private PowerManager.WakeLock wakeLock;
private NowPlayingQueue nowPlayingQueue;
private static Bitmap copy(Bitmap bitmap) {
Bitmap.Config config = bitmap.getConfig();
@ -328,6 +327,8 @@ public class MusicService extends Service implements
public void onCreate() {
super.onCreate();
nowPlayingQueue = new NowPlayingQueue(this);
final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
@ -523,7 +524,7 @@ public class MusicService extends Service implements
}
@Nullable
public ArrayList<Song> getPlayingQueue() {
public List<Song> getPlayingQueue() {
return playingQueue;
}
@ -985,9 +986,10 @@ public class MusicService extends Service implements
public synchronized void restoreQueuesAndPositionIfNecessary() {
if (!queuesRestored && playingQueue.isEmpty()) {
ArrayList<Song> restoredQueue = MusicPlaybackQueueStore.getInstance(this).getSavedPlayingQueue();
ArrayList<Song> restoredOriginalQueue = MusicPlaybackQueueStore.getInstance(this)
.getSavedOriginalPlayingQueue();
List<Song> restoredQueue = nowPlayingQueue.getQueue();//MusicPlaybackQueueStore.getInstance(this).getSavedPlayingQueue();
List<Song> restoredOriginalQueue = nowPlayingQueue.getOriginalQueue();//MusicPlaybackQueueStore.getInstance(this).getSavedOriginalPlayingQueue();
int restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_POSITION, -1);
int restoredPositionInTrack = PreferenceManager.getDefaultSharedPreferences(this)
.getInt(SAVED_POSITION_IN_TRACK, -1);
@ -1023,7 +1025,9 @@ public class MusicService extends Service implements
}
public void saveQueuesImpl() {
MusicPlaybackQueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue);
//MusicPlaybackQueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue);
nowPlayingQueue.saveQueue(playingQueue);
nowPlayingQueue.saveOriginalQueue(originalPlayingQueue);
}
public void saveState() {