use query backend for playlists

This commit is contained in:
dkanada 2020-04-29 18:30:06 +09:00
commit 6592a0e0d5
5 changed files with 16 additions and 287 deletions

View file

@ -7,7 +7,6 @@ import androidx.fragment.app.DialogFragment;
import com.afollestad.materialdialogs.MaterialDialog;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PlaylistsUtil;
@ -36,7 +35,8 @@ public class AddToPlaylistDialog extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final List<Playlist> playlists = PlaylistLoader.getAllPlaylists(getActivity());
final List<Playlist> playlists = new ArrayList<>();
CharSequence[] playlistNames = new CharSequence[playlists.size() + 1];
playlistNames[0] = getActivity().getResources().getString(R.string.action_new_playlist);
for (int i = 1; i < playlistNames.length; i++) {

View file

@ -1,92 +0,0 @@
package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.PlaylistsColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.kabouzeid.gramophone.model.Playlist;
import java.util.ArrayList;
import java.util.List;
public class PlaylistLoader {
@NonNull
public static List<Playlist> getAllPlaylists(@NonNull final Context context) {
return getAllPlaylists(makePlaylistCursor(context, null, null));
}
@NonNull
public static Playlist getPlaylist(@NonNull final Context context, final int playlistId) {
return getPlaylist(makePlaylistCursor(
context,
BaseColumns._ID + "=?",
new String[]{
String.valueOf(playlistId)
}
));
}
@NonNull
public static Playlist getPlaylist(@NonNull final Context context, final String playlistName) {
return getPlaylist(makePlaylistCursor(
context,
PlaylistsColumns.NAME + "=?",
new String[]{
playlistName
}
));
}
@NonNull
public static Playlist getPlaylist(@Nullable final Cursor cursor) {
Playlist playlist = new Playlist();
if (cursor != null && cursor.moveToFirst()) {
playlist = getPlaylistFromCursorImpl(cursor);
}
if (cursor != null)
cursor.close();
return playlist;
}
@NonNull
public static List<Playlist> getAllPlaylists(@Nullable final Cursor cursor) {
List<Playlist> playlists = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
playlists.add(getPlaylistFromCursorImpl(cursor));
} while (cursor.moveToNext());
}
if (cursor != null)
cursor.close();
return playlists;
}
@NonNull
private static Playlist getPlaylistFromCursorImpl(@NonNull final Cursor cursor) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
return new Playlist(id, name);
}
@Nullable
public static Cursor makePlaylistCursor(@NonNull final Context context, final String selection, final String[] values) {
try {
return context.getContentResolver().query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
new String[]{
/* 0 */
BaseColumns._ID,
/* 1 */
PlaylistsColumns.NAME
}, selection, values, MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER);
} catch (SecurityException e) {
return null;
}
}
}

View file

@ -1,170 +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.kabouzeid.gramophone.loader;
import android.database.AbstractCursor;
import android.database.Cursor;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* This cursor basically wraps a song cursor and is given a list of the order of the ids of the
* contents of the cursor. It wraps the Cursor and simulates the internal cursor being sorted
* by moving the point to the appropriate spot
*/
public class SortedCursor extends AbstractCursor {
// cursor to wrap
private final Cursor mCursor;
// the map of external indices to internal indices
private List<Integer> mOrderedPositions;
// this contains the ids that weren't found in the underlying cursor
private List<String> mMissingValues;
// this contains the mapped cursor positions and afterwards the extra ids that weren't found
private HashMap<String, Integer> mMapCursorPositions;
/**
* @param cursor to wrap
* @param order the list of unique ids in sorted order to display
* @param columnName the column name of the id to look up in the internal cursor
*/
public SortedCursor(@NonNull final Cursor cursor, @Nullable final String[] order, final String columnName) {
mCursor = cursor;
mMissingValues = buildCursorPositionMapping(order, columnName);
}
/**
* This function populates mOrderedPositions with the cursor positions in the order based
* on the order passed in
*
* @param order the target order of the internal cursor
* @return returns the ids that aren't found in the underlying cursor
*/
@NonNull
private List<String> buildCursorPositionMapping(@Nullable final String[] order, final String columnName) {
List<String> missingValues = new ArrayList<>();
mOrderedPositions = new ArrayList<>(mCursor.getCount());
mMapCursorPositions = new HashMap<>(mCursor.getCount());
final int valueColumnIndex = mCursor.getColumnIndex(columnName);
if (mCursor.moveToFirst()) {
// first figure out where each of the ids are in the cursor
do {
mMapCursorPositions.put(mCursor.getString(valueColumnIndex), mCursor.getPosition());
} while (mCursor.moveToNext());
if (order != null) {
// now create the ordered positions to map to the internal cursor given the
// external sort order
for (final String value : order) {
if (mMapCursorPositions.containsKey(value)) {
mOrderedPositions.add(mMapCursorPositions.get(value));
mMapCursorPositions.remove(value);
} else {
missingValues.add(value);
}
}
}
mCursor.moveToFirst();
}
return missingValues;
}
/**
* @return the list of ids that weren't found in the underlying cursor
*/
public List<String> getMissingValues() {
return mMissingValues;
}
/**
* @return the list of ids that were in the underlying cursor but not part of the ordered list
*/
@NonNull
public Collection<String> getExtraValues() {
return mMapCursorPositions.keySet();
}
@Override
public void close() {
mCursor.close();
super.close();
}
@Override
public int getCount() {
return mOrderedPositions.size();
}
@Override
public String[] getColumnNames() {
return mCursor.getColumnNames();
}
@Override
public String getString(int column) {
return mCursor.getString(column);
}
@Override
public short getShort(int column) {
return mCursor.getShort(column);
}
@Override
public int getInt(int column) {
return mCursor.getInt(column);
}
@Override
public long getLong(int column) {
return mCursor.getLong(column);
}
@Override
public float getFloat(int column) {
return mCursor.getFloat(column);
}
@Override
public double getDouble(int column) {
return mCursor.getDouble(column);
}
@Override
public boolean isNull(int column) {
return mCursor.isNull(column);
}
@Override
public boolean onMove(int oldPosition, int newPosition) {
if (newPosition >= 0 && newPosition < getCount()) {
mCursor.moveToPosition(mOrderedPositions.get(newPosition));
return true;
}
return false;
}
}

View file

@ -25,7 +25,6 @@ import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.menu.PlaylistMenuHelper;
import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.model.playlist.AbsSmartPlaylist;
@ -78,6 +77,16 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
setUpRecyclerView();
setUpToolbar();
ItemQuery query = new ItemQuery();
query.setParentId(playlist.id);
QueryUtil.getSongs(query, new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
adapter.getDataSet().addAll((List<Song>) media);
adapter.notifyDataSetChanged();
}
});
}
@Override
@ -178,27 +187,10 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
if (!(playlist instanceof AbsSmartPlaylist)) {
// Playlist deleted
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
finish();
return;
}
// Playlist renamed
final String playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.hashCode());
if (!playlistName.equals(playlist.name)) {
playlist = PlaylistLoader.getPlaylist(this, playlist.id);
setToolbarTitle(playlist.name);
}
}
}
private void checkIsEmpty() {
empty.setVisibility(
adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE
);
empty.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
@Override
@ -206,6 +198,7 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager.cancelDrag();
}
super.onPause();
}

View file

@ -12,7 +12,6 @@ import android.widget.Toast;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Genre;
@ -152,15 +151,14 @@ public class MusicUtil {
}
public static Playlist getFavoritesPlaylist(@NonNull final Context context) {
return PlaylistLoader.getPlaylist(context, context.getString(R.string.favorites));
return new Playlist();
}
private static Playlist getOrCreateFavoritesPlaylist(@NonNull final Context context) {
return PlaylistLoader.getPlaylist(context, PlaylistsUtil.createPlaylist(context, context.getString(R.string.favorites)));
return new Playlist();
}
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {
//return PlaylistsUtil.doPlaylistContains(context, getFavoritesPlaylist(context).id, song.id);
return false;
}