Added room for now playing queue
This commit is contained in:
parent
6cdaf27eda
commit
2da9d1c5b7
14 changed files with 211 additions and 25 deletions
|
@ -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"
|
||||
}
|
|
@ -76,7 +76,7 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
|
|||
|
||||
playingQueueAdapter = PlayingQueueAdapter(
|
||||
this,
|
||||
MusicPlayerRemote.playingQueue,
|
||||
MusicPlayerRemote.playingQueue.toMutableList(),
|
||||
MusicPlayerRemote.position,
|
||||
R.layout.item_queue
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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?) :
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue