package io.hefuyi.listener.dataloader; import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.Context; import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; import android.provider.MediaStore; import java.util.ArrayList; import java.util.List; import io.hefuyi.listener.mvp.model.Song; import rx.Observable; public class PlaylistSongLoader { public static Observable<List<Song>> getSongsInPlaylist(Context context, long playlistID) { ArrayList<Song> mSongList = new ArrayList<>(); final int playlistCount = countPlaylist(context, playlistID); Cursor cursor = makePlaylistSongCursor(context, playlistID); if (cursor != null) { boolean runCleanup = false; if (cursor.getCount() != playlistCount) { runCleanup = true; } if (!runCleanup && cursor.moveToFirst()) { final int playOrderCol = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.PLAY_ORDER); int lastPlayOrder = -1; do { int playOrder = cursor.getInt(playOrderCol); if (playOrder == lastPlayOrder) { runCleanup = true; break; } lastPlayOrder = playOrder; } while (cursor.moveToNext()); } if (runCleanup) { cleanupPlaylist(context, playlistID, cursor); cursor.close(); cursor = makePlaylistSongCursor(context, playlistID); if (cursor != null) { } } } if (cursor != null && cursor.moveToFirst()) { do { final long id = cursor.getLong(cursor .getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.AUDIO_ID)); final String songName = cursor.getString(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.TITLE)); final String artist = cursor.getString(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ARTIST)); final long albumId = cursor.getLong(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM_ID)); final long artistId = cursor.getLong(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ARTIST_ID)); final String album = cursor.getString(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM)); final long duration = cursor.getLong(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DURATION)); final int durationInSecs = (int) duration / 1000; final int tracknumber = cursor.getInt(cursor .getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.TRACK)); final Song song = new Song(id, albumId, artistId, songName, artist, album, durationInSecs, tracknumber); mSongList.add(song); } while (cursor.moveToNext()); } // Close the cursor if (cursor != null) { cursor.close(); cursor = null; } return Observable.from(mSongList).toList(); } /** * 清空某playlist,用cursor填充 * @param context * @param playlistId * @param cursor */ private static void cleanupPlaylist(final Context context, final long playlistId, final Cursor cursor) { final int idCol = cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.AUDIO_ID); final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId); ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); ops.add(ContentProviderOperation.newDelete(uri).build()); final int YIELD_FREQUENCY = 100; if (cursor.moveToFirst() && cursor.getCount() > 0) { do { final ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri) .withValue(MediaStore.Audio.Playlists.Members.PLAY_ORDER, cursor.getPosition()) .withValue(MediaStore.Audio.Playlists.Members.AUDIO_ID, cursor.getLong(idCol)); if ((cursor.getPosition() + 1) % YIELD_FREQUENCY == 0) { builder.withYieldAllowed(true); } ops.add(builder.build()); } while (cursor.moveToNext()); } try { context.getContentResolver().applyBatch(MediaStore.AUTHORITY, ops); } catch (RemoteException e) { } catch (OperationApplicationException e) { } } /** * 计算某playlist中媒体文件的数量 * @param context * @param playlistId * @return */ private static int countPlaylist(final Context context, final long playlistId) { Cursor c = null; try { c = context.getContentResolver().query( MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId), new String[]{ MediaStore.Audio.Playlists.Members.AUDIO_ID, }, null, null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER); if (c != null) { return c.getCount(); } } finally { if (c != null) { c.close(); c = null; } } return 0; } public static void removeFromPlaylist(final Context context, final long[] ids, final long playlistId) { final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId); final ContentResolver resolver = context.getContentResolver(); final StringBuilder selection = new StringBuilder(); selection.append(MediaStore.Audio.Playlists.Members.AUDIO_ID + " IN ("); for (int i = 0; i < ids.length; i++) { selection.append(ids[i]); if (i < ids.length - 1) { selection.append(","); } } selection.append(")"); resolver.delete(uri, selection.toString(), null); } /** * 获取某playlist中规范音乐文件的数量 * @param context * @param playlistID * @return */ private static Cursor makePlaylistSongCursor(final Context context, final Long playlistID) { final StringBuilder mSelection = new StringBuilder(); mSelection.append(MediaStore.Audio.AudioColumns.IS_MUSIC + "=1"); mSelection.append(" AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"); return context.getContentResolver().query( MediaStore.Audio.Playlists.Members.getContentUri("external", playlistID), new String[]{ MediaStore.Audio.Playlists.Members._ID, MediaStore.Audio.Playlists.Members.AUDIO_ID, MediaStore.Audio.AudioColumns.TITLE, MediaStore.Audio.AudioColumns.ARTIST, MediaStore.Audio.AudioColumns.ALBUM_ID, MediaStore.Audio.AudioColumns.ARTIST_ID, MediaStore.Audio.AudioColumns.ALBUM, MediaStore.Audio.AudioColumns.DURATION, MediaStore.Audio.AudioColumns.TRACK, MediaStore.Audio.Playlists.Members.PLAY_ORDER, }, mSelection.toString(), null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER); } }