PlayerAndroid/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java

277 lines
11 KiB
Java
Raw Normal View History

2019-03-03 09:29:03 +00:00
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
2018-07-27 13:07:33 +00:00
package code.name.monkey.retromusic.util;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.widget.Toast;
2019-08-01 08:27:05 +00:00
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
2018-07-27 13:07:33 +00:00
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.helper.M3UWriter;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.PlaylistSong;
import code.name.monkey.retromusic.model.Song;
import static android.provider.MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
2018-07-27 13:07:33 +00:00
public class PlaylistsUtil {
2020-02-01 14:22:57 +00:00
public static void addToPlaylist(@NonNull Context context,
@NonNull List<Song> songs,
int playlistId,
boolean showToastOnFinish) {
2020-02-01 14:22:57 +00:00
ArrayList<Song> noSongs = new ArrayList<Song>();
for (Song song : songs) {
if (!doPlaylistContains(context, playlistId, song.getId())) {
noSongs.add(song);
}
}
final int size = noSongs.size();
final ContentResolver resolver = context.getContentResolver();
final String[] projection = new String[]{"max(" + MediaStore.Audio.Playlists.Members.PLAY_ORDER + ")",};
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
int base = 0;
try (Cursor cursor = resolver.query(uri, projection, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
base = cursor.getInt(0) + 1;
}
} catch (SecurityException ignored) {
}
int numInserted = 0;
for (int offSet = 0; offSet < size; offSet += 1000) {
numInserted += resolver.bulkInsert(uri, makeInsertItems(noSongs, offSet, 1000, base));
}
if (showToastOnFinish) {
Toast.makeText(context, context.getResources().getString(
R.string.inserted_x_songs_into_playlist_x, numInserted, getNameForPlaylist(context, playlistId)),
Toast.LENGTH_SHORT).show();
}
2018-07-27 13:07:33 +00:00
}
public static int createPlaylist(@NonNull final Context context, @Nullable final String name) {
int id = -1;
if (name != null && name.length() > 0) {
try {
2020-02-01 14:22:57 +00:00
Cursor cursor = context.getContentResolver()
.query(EXTERNAL_CONTENT_URI, new String[]{MediaStore.Audio.Playlists._ID},
MediaStore.Audio.PlaylistsColumns.NAME + "=?", new String[]{name}, null);
2018-07-27 13:07:33 +00:00
if (cursor == null || cursor.getCount() < 1) {
final ContentValues values = new ContentValues(1);
values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
2020-02-01 14:22:57 +00:00
final Uri uri = context.getContentResolver().insert(EXTERNAL_CONTENT_URI, values);
2018-07-27 13:07:33 +00:00
if (uri != null) {
2020-02-01 14:22:57 +00:00
Toast.makeText(context, context.getResources().getString(R.string.created_playlist_x, name),
Toast.LENGTH_SHORT).show();
2018-07-27 13:07:33 +00:00
id = Integer.parseInt(uri.getLastPathSegment());
}
} else {
// Playlist exists
2018-07-27 13:07:33 +00:00
if (cursor.moveToFirst()) {
id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Playlists._ID));
}
}
if (cursor != null) {
cursor.close();
}
} catch (SecurityException ignored) {
}
}
if (id == -1) {
Toast.makeText(context, context.getResources().getString(
R.string.could_not_create_playlist), Toast.LENGTH_SHORT).show();
}
return id;
}
public static void deletePlaylists(@NonNull final Context context, @NonNull final ArrayList<Playlist> playlists) {
final StringBuilder selection = new StringBuilder();
selection.append(MediaStore.Audio.Playlists._ID + " IN (");
for (int i = 0; i < playlists.size(); i++) {
selection.append(playlists.get(i).id);
2018-07-27 13:07:33 +00:00
if (i < playlists.size() - 1) {
selection.append(",");
}
}
selection.append(")");
try {
context.getContentResolver().delete(EXTERNAL_CONTENT_URI, selection.toString(), null);
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
2018-07-27 13:07:33 +00:00
} catch (SecurityException ignored) {
}
}
2020-02-01 17:53:26 +00:00
static boolean doPlaylistContains(@NonNull final Context context, final long playlistId,
final int songId) {
2020-02-01 14:22:57 +00:00
if (playlistId != -1) {
try {
Cursor c = context.getContentResolver().query(
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
new String[]{MediaStore.Audio.Playlists.Members.AUDIO_ID},
MediaStore.Audio.Playlists.Members.AUDIO_ID + "=?", new String[]{String.valueOf(songId)},
null);
int count = 0;
if (c != null) {
count = c.getCount();
c.close();
}
return count > 0;
} catch (SecurityException ignored) {
2019-11-04 16:26:18 +00:00
}
}
2020-02-01 14:22:57 +00:00
return false;
}
2019-11-04 16:26:18 +00:00
2020-02-01 14:22:57 +00:00
public static boolean doesPlaylistExist(@NonNull final Context context, final int playlistId) {
return playlistId != -1 && doesPlaylistExist(context,
MediaStore.Audio.Playlists._ID + "=?",
new String[]{String.valueOf(playlistId)});
}
2019-11-04 16:26:18 +00:00
2020-02-01 14:22:57 +00:00
public static String getNameForPlaylist(@NonNull final Context context, final long id) {
try {
Cursor cursor = context.getContentResolver().query(EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.PlaylistsColumns.NAME},
BaseColumns._ID + "=?",
new String[]{String.valueOf(id)},
null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
return cursor.getString(0);
}
} finally {
cursor.close();
}
2018-07-27 13:07:33 +00:00
}
} catch (SecurityException ignored) {
}
2020-02-01 14:22:57 +00:00
return "";
2018-07-27 13:07:33 +00:00
}
@NonNull
2020-02-01 14:22:57 +00:00
public static ContentValues[] makeInsertItems(@NonNull final List<Song> songs, final int offset, int len,
final int base) {
2018-07-27 13:07:33 +00:00
if (offset + len > songs.size()) {
len = songs.size() - offset;
}
ContentValues[] contentValues = new ContentValues[len];
for (int i = 0; i < len; i++) {
contentValues[i] = new ContentValues();
contentValues[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
contentValues[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(offset + i).getId());
2018-07-27 13:07:33 +00:00
}
return contentValues;
}
2020-02-01 14:22:57 +00:00
public static boolean moveItem(@NonNull final Context context, int playlistId, int from, int to) {
return MediaStore.Audio.Playlists.Members.moveItem(context.getContentResolver(),
playlistId, from, to);
}
2018-07-27 13:07:33 +00:00
public static void removeFromPlaylist(@NonNull final Context context, @NonNull final Song song, int playlistId) {
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri(
"external", playlistId);
String selection = MediaStore.Audio.Playlists.Members.AUDIO_ID + " =?";
2019-03-04 03:55:09 +00:00
String[] selectionArgs = new String[]{String.valueOf(song.getId())};
2018-07-27 13:07:33 +00:00
try {
context.getContentResolver().delete(uri, selection, selectionArgs);
} catch (SecurityException ignored) {
}
}
public static void removeFromPlaylist(@NonNull final Context context, @NonNull final List<PlaylistSong> songs) {
2019-03-04 03:55:09 +00:00
final int playlistId = songs.get(0).getPlaylistId();
2018-07-27 13:07:33 +00:00
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri(
"external", playlistId);
String selectionArgs[] = new String[songs.size()];
for (int i = 0; i < selectionArgs.length; i++) {
2019-03-04 03:55:09 +00:00
selectionArgs[i] = String.valueOf(songs.get(i).getIdInPlayList());
2018-07-27 13:07:33 +00:00
}
String selection = MediaStore.Audio.Playlists.Members._ID + " in (";
//noinspection unused
2020-02-01 14:22:57 +00:00
for (String selectionArg : selectionArgs) {
selection += "?, ";
}
2018-07-27 13:07:33 +00:00
selection = selection.substring(0, selection.length() - 2) + ")";
try {
context.getContentResolver().delete(uri, selection, selectionArgs);
} catch (SecurityException ignored) {
}
}
public static void renamePlaylist(@NonNull final Context context, final long id, final String newName) {
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Audio.PlaylistsColumns.NAME, newName);
try {
context.getContentResolver().update(EXTERNAL_CONTENT_URI,
contentValues,
MediaStore.Audio.Playlists._ID + "=?",
new String[]{String.valueOf(id)});
} catch (SecurityException ignored) {
}
}
@Nullable
public static File savePlaylist(@NonNull Context context,
@NonNull Playlist playlist) throws IOException {
return M3UWriter.write(context, new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
}
2020-02-01 14:22:57 +00:00
static void addToPlaylist(@NonNull Context context,
@NonNull Song song,
int playlistId,
boolean showToastOnFinish) {
2020-02-01 14:22:57 +00:00
List<Song> helperList = new ArrayList<>();
helperList.add(song);
addToPlaylist(context, helperList, playlistId, showToastOnFinish);
}
private static boolean doesPlaylistExist(@NonNull Context context, @NonNull final String selection,
@NonNull final String[] values) {
Cursor cursor = context.getContentResolver().query(EXTERNAL_CONTENT_URI,
new String[]{}, selection, values, null);
boolean exists = false;
if (cursor != null) {
exists = cursor.getCount() != 0;
cursor.close();
}
return exists;
2018-07-27 13:07:33 +00:00
}
}