use query backend for playlists
This commit is contained in:
parent
1366060040
commit
6592a0e0d5
5 changed files with 16 additions and 287 deletions
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue