replace queue store with room database
This commit is contained in:
parent
bb2793dbea
commit
44c1bb63b6
10 changed files with 150 additions and 324 deletions
|
|
@ -78,6 +78,9 @@ dependencies {
|
||||||
implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
|
implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
|
||||||
implementation 'com.android.support:multidex:1.0.3'
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
|
|
||||||
|
implementation 'androidx.room:room-runtime:2.2.5'
|
||||||
|
annotationProcessor 'androidx.room:room-compiler:2.2.5'
|
||||||
|
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.room.Room;
|
||||||
|
|
||||||
|
import com.dkanada.gramophone.database.JellyDatabase;
|
||||||
import com.dkanada.gramophone.helper.EventListener;
|
import com.dkanada.gramophone.helper.EventListener;
|
||||||
import com.dkanada.gramophone.util.PreferenceUtil;
|
import com.dkanada.gramophone.util.PreferenceUtil;
|
||||||
import com.kabouzeid.appthemehelper.ThemeStore;
|
import com.kabouzeid.appthemehelper.ThemeStore;
|
||||||
|
|
@ -22,6 +25,7 @@ import org.jellyfin.apiclient.logging.ILogger;
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
private static App app;
|
private static App app;
|
||||||
|
|
||||||
|
private static JellyDatabase database;
|
||||||
private static ApiClient apiClient;
|
private static ApiClient apiClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -29,6 +33,7 @@ public class App extends Application {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
app = this;
|
app = this;
|
||||||
|
database = createDatabase(this);
|
||||||
apiClient = createApiClient(this);
|
apiClient = createApiClient(this);
|
||||||
|
|
||||||
// default theme
|
// default theme
|
||||||
|
|
@ -42,6 +47,12 @@ public class App extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JellyDatabase createDatabase(Context context) {
|
||||||
|
return Room.databaseBuilder(context, JellyDatabase.class, "database")
|
||||||
|
.allowMainThreadQueries()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static ApiClient createApiClient(Context context) {
|
public static ApiClient createApiClient(Context context) {
|
||||||
String appName = context.getString(R.string.app_name);
|
String appName = context.getString(R.string.app_name);
|
||||||
String appVersion = BuildConfig.VERSION_NAME;
|
String appVersion = BuildConfig.VERSION_NAME;
|
||||||
|
|
@ -59,6 +70,10 @@ public class App extends Application {
|
||||||
return new ApiClient(httpClient, logger, server, appName, appVersion, device, eventListener);
|
return new ApiClient(httpClient, logger, server, appName, appVersion, device, eventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JellyDatabase getDatabase() {
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
|
||||||
public static ApiClient getApiClient() {
|
public static ApiClient getApiClient() {
|
||||||
return apiClient;
|
return apiClient;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.dkanada.gramophone.database;
|
||||||
|
|
||||||
|
import androidx.room.RoomDatabase;
|
||||||
|
|
||||||
|
import com.dkanada.gramophone.model.Song;
|
||||||
|
|
||||||
|
@androidx.room.Database(
|
||||||
|
entities = {
|
||||||
|
Song.class,
|
||||||
|
QueueSong.class
|
||||||
|
},
|
||||||
|
version = 1,
|
||||||
|
exportSchema = false
|
||||||
|
)
|
||||||
|
public abstract class JellyDatabase extends RoomDatabase {
|
||||||
|
public abstract QueueSongDao queueSongDao();
|
||||||
|
public abstract SongDao songDao();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.dkanada.gramophone.database;
|
||||||
|
|
||||||
|
import androidx.room.Entity;
|
||||||
|
import androidx.room.ForeignKey;
|
||||||
|
|
||||||
|
import com.dkanada.gramophone.model.Song;
|
||||||
|
|
||||||
|
@Entity(
|
||||||
|
tableName = "queueSongs",
|
||||||
|
primaryKeys = {
|
||||||
|
"index",
|
||||||
|
"queue"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public class QueueSong {
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
public int queue;
|
||||||
|
|
||||||
|
@ForeignKey(
|
||||||
|
entity = Song.class,
|
||||||
|
parentColumns = {"id"},
|
||||||
|
childColumns = {"songId"},
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)
|
||||||
|
public String songId;
|
||||||
|
|
||||||
|
public QueueSong(String songId, int index, int queue) {
|
||||||
|
this.songId = songId;
|
||||||
|
|
||||||
|
this.index = index;
|
||||||
|
this.queue = queue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.dkanada.gramophone.database;
|
||||||
|
|
||||||
|
import androidx.room.Dao;
|
||||||
|
import androidx.room.Insert;
|
||||||
|
import androidx.room.OnConflictStrategy;
|
||||||
|
import androidx.room.Query;
|
||||||
|
|
||||||
|
import com.dkanada.gramophone.App;
|
||||||
|
import com.dkanada.gramophone.model.Song;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
public abstract class QueueSongDao {
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
public abstract void insertQueueSongs(List<QueueSong> queueSongs);
|
||||||
|
|
||||||
|
@Query("DELETE FROM queueSongs")
|
||||||
|
public abstract void deleteQueueSongs();
|
||||||
|
|
||||||
|
@Query("SELECT * from queueSongs WHERE queue = :queue ORDER BY `index`")
|
||||||
|
public abstract List<QueueSong> getQueueSongs(int queue);
|
||||||
|
|
||||||
|
public List<Song> getQueue(int queue) {
|
||||||
|
List<QueueSong> queueSongs = getQueueSongs(queue);
|
||||||
|
List<Song> songs = new ArrayList<>();
|
||||||
|
|
||||||
|
for (QueueSong queueSong : queueSongs) {
|
||||||
|
Song song = App.getDatabase().songDao().getSong(queueSong.songId);
|
||||||
|
if (song != null) songs.add(song);
|
||||||
|
}
|
||||||
|
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueue(List<Song> songs, int queue) {
|
||||||
|
List<QueueSong> queueSongs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < songs.size(); i++) {
|
||||||
|
queueSongs.add(new QueueSong(songs.get(i).id, i, queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
insertQueueSongs(queueSongs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.dkanada.gramophone.database;
|
||||||
|
|
||||||
|
import androidx.room.Dao;
|
||||||
|
import androidx.room.Insert;
|
||||||
|
import androidx.room.OnConflictStrategy;
|
||||||
|
import androidx.room.Query;
|
||||||
|
|
||||||
|
import com.dkanada.gramophone.model.Song;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
public interface SongDao {
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
void insertSongs(List<Song> songs);
|
||||||
|
|
||||||
|
@Query("DELETE FROM songs")
|
||||||
|
void deleteSongs();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM songs WHERE id = :id")
|
||||||
|
Song getSong(String id);
|
||||||
|
}
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
package com.dkanada.gramophone.loader;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.provider.BaseColumns;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.provider.MediaStore.Audio.AudioColumns;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.dkanada.gramophone.model.Song;
|
|
||||||
import com.dkanada.gramophone.util.PreferenceUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SongLoader {
|
|
||||||
public static final String QUEUE_PRIMARY = "image";
|
|
||||||
public static final String QUEUE_FAVORITE = "favorite";
|
|
||||||
|
|
||||||
protected static final String BASE_SELECTION = AudioColumns.IS_MUSIC + "=1" + " AND " + AudioColumns.TITLE + " != ''";
|
|
||||||
protected static final String[] BASE_PROJECTION = new String[]{
|
|
||||||
BaseColumns._ID,
|
|
||||||
AudioColumns.TITLE,
|
|
||||||
AudioColumns.TRACK,
|
|
||||||
AudioColumns.YEAR,
|
|
||||||
AudioColumns.DURATION,
|
|
||||||
AudioColumns.ALBUM_ID,
|
|
||||||
AudioColumns.ALBUM,
|
|
||||||
AudioColumns.ARTIST_ID,
|
|
||||||
AudioColumns.ARTIST,
|
|
||||||
QUEUE_PRIMARY,
|
|
||||||
QUEUE_FAVORITE,
|
|
||||||
};
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static List<Song> getAllSongs(@NonNull Context context) {
|
|
||||||
Cursor cursor = makeSongCursor(context, null, null);
|
|
||||||
return getSongs(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static List<Song> getSongs(@Nullable final Cursor cursor) {
|
|
||||||
List<Song> songs = new ArrayList<>();
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
songs.add(getSongFromCursorImpl(cursor));
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor != null) cursor.close();
|
|
||||||
return songs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static Song getSong(@Nullable Cursor cursor) {
|
|
||||||
Song song;
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
song = getSongFromCursorImpl(cursor);
|
|
||||||
} else {
|
|
||||||
song = Song.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private static Song getSongFromCursorImpl(@NonNull Cursor cursor) {
|
|
||||||
final String id = cursor.getString(0);
|
|
||||||
final String title = cursor.getString(1);
|
|
||||||
final int trackNumber = cursor.getInt(2);
|
|
||||||
final int year = cursor.getInt(3);
|
|
||||||
final long duration = cursor.getLong(4);
|
|
||||||
|
|
||||||
final String albumId = cursor.getString(5);
|
|
||||||
final String albumName = cursor.getString(6);
|
|
||||||
|
|
||||||
final String artistId = cursor.getString(7);
|
|
||||||
final String artistName = cursor.getString(8);
|
|
||||||
|
|
||||||
final String primary = cursor.getString(9);
|
|
||||||
final boolean favorite = Boolean.valueOf(cursor.getString(10));
|
|
||||||
|
|
||||||
return new Song(id, title, trackNumber, 1, year, duration, albumId, albumName, artistId, artistName, primary, favorite);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Cursor makeSongCursor(@NonNull final Context context, @Nullable final String selection, final String[] selectionValues) {
|
|
||||||
return makeSongCursor(context, selection, selectionValues, PreferenceUtil.getInstance(context).getSongSortOrder());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Cursor makeSongCursor(@NonNull final Context context, @Nullable String selection, String[] selectionValues, final String sortOrder) {
|
|
||||||
if (selection != null && !selection.trim().equals("")) {
|
|
||||||
selection = BASE_SELECTION + " AND " + selection;
|
|
||||||
} else {
|
|
||||||
selection = BASE_SELECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
|
|
||||||
BASE_PROJECTION, selection, selectionValues, sortOrder);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,6 +4,8 @@ import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.room.Entity;
|
||||||
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
||||||
import org.jellyfin.apiclient.model.dto.MediaSourceInfo;
|
import org.jellyfin.apiclient.model.dto.MediaSourceInfo;
|
||||||
|
|
@ -12,9 +14,12 @@ import org.jellyfin.apiclient.model.entities.MediaStream;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity(tableName = "songs")
|
||||||
public class Song implements Parcelable {
|
public class Song implements Parcelable {
|
||||||
public static final Song EMPTY = new Song();
|
public static final Song EMPTY = new Song();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@PrimaryKey
|
||||||
public String id;
|
public String id;
|
||||||
public String title;
|
public String title;
|
||||||
public int trackNumber;
|
public int trackNumber;
|
||||||
|
|
@ -93,24 +98,6 @@ public class Song implements Parcelable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Song(String id, String title, int trackNumber, int discNumber, int year, long duration, String albumId, String albumName, String artistId, String artistName, String primary, boolean favorite) {
|
|
||||||
this.id = id;
|
|
||||||
this.title = title;
|
|
||||||
this.trackNumber = trackNumber;
|
|
||||||
this.discNumber = discNumber;
|
|
||||||
this.year = year;
|
|
||||||
this.duration = duration;
|
|
||||||
|
|
||||||
this.albumId = albumId;
|
|
||||||
this.albumName = albumName;
|
|
||||||
|
|
||||||
this.artistId = artistId;
|
|
||||||
this.artistName = artistName;
|
|
||||||
|
|
||||||
this.primary = primary;
|
|
||||||
this.favorite = favorite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 The CyanogenMod Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dkanada.gramophone.provider;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.provider.BaseColumns;
|
|
||||||
import android.provider.MediaStore.Audio.AudioColumns;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.dkanada.gramophone.App;
|
|
||||||
import com.dkanada.gramophone.loader.SongLoader;
|
|
||||||
import com.dkanada.gramophone.model.Song;
|
|
||||||
import com.dkanada.gramophone.util.PreferenceUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class QueueStore extends SQLiteOpenHelper {
|
|
||||||
@Nullable
|
|
||||||
private static QueueStore sInstance = null;
|
|
||||||
public static final String DATABASE_NAME = "music_playback_state.db";
|
|
||||||
public static final String PLAYING_QUEUE_TABLE_NAME = "playing_queue";
|
|
||||||
public static final String ORIGINAL_PLAYING_QUEUE_TABLE_NAME = "original_playing_queue";
|
|
||||||
private static final int VERSION = 5;
|
|
||||||
|
|
||||||
public QueueStore(final Context context) {
|
|
||||||
super(context, DATABASE_NAME, null, VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@NonNull final SQLiteDatabase db) {
|
|
||||||
createTable(db, PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
createTable(db, ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createTable(@NonNull final SQLiteDatabase db, final String tableName) {
|
|
||||||
// noinspection StringBufferReplaceableByString
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("CREATE TABLE IF NOT EXISTS ");
|
|
||||||
builder.append(tableName);
|
|
||||||
builder.append("(");
|
|
||||||
|
|
||||||
builder.append(BaseColumns._ID);
|
|
||||||
builder.append(" INT NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.TITLE);
|
|
||||||
builder.append(" STRING NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.TRACK);
|
|
||||||
builder.append(" INT NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.YEAR);
|
|
||||||
builder.append(" INT NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.DURATION);
|
|
||||||
builder.append(" LONG NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.ALBUM_ID);
|
|
||||||
builder.append(" INT NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.ALBUM);
|
|
||||||
builder.append(" STRING NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.ARTIST_ID);
|
|
||||||
builder.append(" INT NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(AudioColumns.ARTIST);
|
|
||||||
builder.append(" STRING NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(SongLoader.QUEUE_PRIMARY);
|
|
||||||
builder.append(" STRING NOT NULL,");
|
|
||||||
|
|
||||||
builder.append(SongLoader.QUEUE_FAVORITE);
|
|
||||||
builder.append(" STRING NOT NULL);");
|
|
||||||
|
|
||||||
db.execSQL(builder.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDowngrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
db.execSQL("DROP TABLE IF EXISTS " + ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
onCreate(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static synchronized QueueStore getInstance(@NonNull final Context context) {
|
|
||||||
if (sInstance == null) {
|
|
||||||
sInstance = new QueueStore(context.getApplicationContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void saveQueues(@NonNull final List<Song> playingQueue, @NonNull final List<Song> originalPlayingQueue) {
|
|
||||||
saveQueue(PLAYING_QUEUE_TABLE_NAME, playingQueue);
|
|
||||||
saveQueue(ORIGINAL_PLAYING_QUEUE_TABLE_NAME, originalPlayingQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void saveQueue(final String tableName, @NonNull final List<Song> queue) {
|
|
||||||
final SQLiteDatabase database = getWritableDatabase();
|
|
||||||
database.beginTransaction();
|
|
||||||
|
|
||||||
try {
|
|
||||||
database.delete(tableName, null, null);
|
|
||||||
database.setTransactionSuccessful();
|
|
||||||
} finally {
|
|
||||||
database.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int NUM_PROCESS = 20;
|
|
||||||
int position = 0;
|
|
||||||
while (position < queue.size()) {
|
|
||||||
database.beginTransaction();
|
|
||||||
try {
|
|
||||||
for (int i = position; i < queue.size() && i < position + NUM_PROCESS; i++) {
|
|
||||||
Song song = queue.get(i);
|
|
||||||
ContentValues values = new ContentValues(4);
|
|
||||||
|
|
||||||
values.put(BaseColumns._ID, song.id);
|
|
||||||
values.put(AudioColumns.TITLE, song.title);
|
|
||||||
values.put(AudioColumns.TRACK, song.trackNumber);
|
|
||||||
values.put(AudioColumns.YEAR, song.year);
|
|
||||||
values.put(AudioColumns.DURATION, song.duration);
|
|
||||||
values.put(AudioColumns.ALBUM_ID, song.albumId);
|
|
||||||
values.put(AudioColumns.ALBUM, song.albumName);
|
|
||||||
values.put(AudioColumns.ARTIST_ID, song.artistId);
|
|
||||||
values.put(AudioColumns.ARTIST, song.artistName);
|
|
||||||
values.put(SongLoader.QUEUE_PRIMARY, song.primary);
|
|
||||||
values.put(SongLoader.QUEUE_FAVORITE, song.favorite);
|
|
||||||
|
|
||||||
database.insert(tableName, null, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
database.setTransactionSuccessful();
|
|
||||||
} finally {
|
|
||||||
database.endTransaction();
|
|
||||||
position += NUM_PROCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public List<Song> getSavedPlayingQueue() {
|
|
||||||
return getQueue(PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public List<Song> getSavedOriginalPlayingQueue() {
|
|
||||||
return getQueue(ORIGINAL_PLAYING_QUEUE_TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private List<Song> getQueue(@NonNull final String tableName) {
|
|
||||||
if (!PreferenceUtil.getInstance(App.getInstance()).getRememberQueue()) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Cursor cursor = getReadableDatabase().query(tableName, null,
|
|
||||||
null, null, null, null, null);
|
|
||||||
return SongLoader.getSongs(cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -42,7 +42,6 @@ import com.dkanada.gramophone.glide.CustomGlideRequest;
|
||||||
import com.dkanada.gramophone.helper.ShuffleHelper;
|
import com.dkanada.gramophone.helper.ShuffleHelper;
|
||||||
import com.dkanada.gramophone.model.Playlist;
|
import com.dkanada.gramophone.model.Playlist;
|
||||||
import com.dkanada.gramophone.model.Song;
|
import com.dkanada.gramophone.model.Song;
|
||||||
import com.dkanada.gramophone.provider.QueueStore;
|
|
||||||
import com.dkanada.gramophone.service.notification.PlayingNotification;
|
import com.dkanada.gramophone.service.notification.PlayingNotification;
|
||||||
import com.dkanada.gramophone.service.notification.PlayingNotificationImpl;
|
import com.dkanada.gramophone.service.notification.PlayingNotificationImpl;
|
||||||
import com.dkanada.gramophone.service.notification.PlayingNotificationImpl24;
|
import com.dkanada.gramophone.service.notification.PlayingNotificationImpl24;
|
||||||
|
|
@ -395,7 +394,12 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveQueue() {
|
private void saveQueue() {
|
||||||
QueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue);
|
App.getDatabase().songDao().deleteSongs();
|
||||||
|
App.getDatabase().songDao().insertSongs(playingQueue);
|
||||||
|
|
||||||
|
App.getDatabase().queueSongDao().deleteQueueSongs();
|
||||||
|
App.getDatabase().queueSongDao().setQueue(playingQueue, 0);
|
||||||
|
App.getDatabase().queueSongDao().setQueue(originalPlayingQueue, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void savePosition() {
|
private void savePosition() {
|
||||||
|
|
@ -427,8 +431,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
|
|
||||||
private synchronized void restoreQueuesAndPositionIfNecessary() {
|
private synchronized void restoreQueuesAndPositionIfNecessary() {
|
||||||
if (!queuesRestored && playingQueue.isEmpty()) {
|
if (!queuesRestored && playingQueue.isEmpty()) {
|
||||||
List<Song> restoredQueue = QueueStore.getInstance(this).getSavedPlayingQueue();
|
List<Song> restoredQueue = App.getDatabase().queueSongDao().getQueue(0);
|
||||||
List<Song> restoredOriginalQueue = QueueStore.getInstance(this).getSavedOriginalPlayingQueue();
|
List<Song> restoredOriginalQueue = App.getDatabase().queueSongDao().getQueue(1);
|
||||||
|
|
||||||
int restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(PreferenceUtil.POSITION, -1);
|
int restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(PreferenceUtil.POSITION, -1);
|
||||||
int restoredPositionInTrack = PreferenceManager.getDefaultSharedPreferences(this).getInt(PreferenceUtil.PROGRESS, -1);
|
int restoredPositionInTrack = PreferenceManager.getDefaultSharedPreferences(this).getInt(PreferenceUtil.PROGRESS, -1);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue