package com.nf2m.model; import android.app.SearchManager; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.media.RingtoneManager; import android.net.Uri; import android.provider.BaseColumns; import android.provider.MediaStore; import android.provider.MediaStore.Audio.PlaylistsColumns; import android.provider.MediaStore.MediaColumns; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.nf2m.fragment.NowPlayingFragment; import com.nf2m.preferences.Preferences; import com.nf2m.service.MediaPlayerService; import java.io.File; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public abstract class Library { private final Uri songUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; private Uri uri; private Cursor cursor; private String sortOrder; private ContentResolver resolver; private Context context; private Preferences preferences; private String selection; private String[] selectionArgs; @Nullable public Cursor initCursor(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { this.uri = uri; this.sortOrder = sortOrder; preferences = Preferences.newInstance(getContext()); this.selection = selection; this.selectionArgs = selectionArgs; return resolver.query(uri, projection, selection, selectionArgs, sortOrder); } @Nullable public Cursor requery() { return resolver.query(uri, null, selection, selectionArgs, sortOrder); } // get ve set metodları public Uri getUri() { return uri; } void setUri(Uri uri) { this.uri = uri; } public Cursor getCursor() { return cursor; } void setCursor(Cursor cursor) { this.cursor = cursor; } public String getSortOrder() { return sortOrder; } void setSortOrder(String sortOrder) { this.sortOrder = sortOrder; } void setResolver(ContentResolver resolver) { this.resolver = resolver; } private Context getContext() { return context; } void setContext(Context context) { this.context = context; } // ------------------DELETE SONGS--------------------------------------- /** * Cursor içindeki tüm şarkıları tek tek data yolları alınır ve bir dosya * nesnesi oluşturulur.Bu şekilde tek tek silinir. Eğer işlem başarılı * olursa veri tabanındaan aynı şarkı silinir. */ public boolean deletedSongs(@NonNull Cursor songCursor) { if (cursorIsNull(songCursor) || cursorIsEmpty(songCursor)) { return false; } int playing_position = preferences.getPrefSongPosition(); int playPos = checkPlayingSong(playing_position); //eğer varsa oynatılan pozisyonda bir şarkı varsa bir şey yapılmaz. //yoksa listenin başına geçilir. if (playPos != -1) { if (!songCursor.moveToPosition(playing_position)) { preferences.setPrefSongPos(0); preferences.setPrefDuration(0); } if (NowPlayingFragment.play_state.equalsIgnoreCase(NowPlayingFragment.PAUSE)) { getContext().sendBroadcast(new Intent(MediaPlayerService.ACTION_PLAY)); } } List<String> songIds = getSongIds(songCursor); String selection = getSelection(songIds); int deletedRows = deleteSongInDatabase(selection); if (deletedRows != 0) { //hafızadan ve audiosdan silinir. songCursor.moveToFirst(); do { deleteSongFileInMemory(songCursor); } while (songCursor.moveToNext()); preferences.setPrefDuration(0); preferences.setPrefSongPos(0); context.sendBroadcast(new Intent(MediaPlayerService.ACTION_NWP_UPDATE)); notifyChangeDatabase(Uri.parse("content://media")); } else { songCursor.close(); return false; } songCursor.close(); return true; } private int checkPlayingSong(int pos) { if (MediaPlayerService.songsCursor.moveToPosition(pos)) { String id = MediaPlayerService.songsCursor.getString(MediaPlayerService.songsCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns._ID)); Cursor cursor = getContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Audio.AudioColumns._ID + " =? ", new String[]{id}, null); if (cursor != null && cursor.getCount() != 0) { int position = cursor.getPosition(); cursor.close(); return position; } } return -1; } @NonNull private List<String> getSongIds(@NonNull Cursor songCursor) { List<String> stringList = new LinkedList<>(); songCursor.moveToFirst(); do { stringList.add(songCursor.getString( songCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns._ID))); } while (songCursor.moveToNext()); return stringList; } private String getSelection(@NonNull List<String> selectionArgs) { String selection; selection = MediaStore.Audio.AudioColumns._ID + " IN ( "; int i = 0; for (String selectionArg : selectionArgs) { if (i == 0) { selection += selectionArg; } else { selection += " , " + selectionArg; } i++; } selection += " ) "; return selection; } /** * Cursor boşdur. */ private boolean cursorIsEmpty(@NonNull final Cursor cursor) { return cursor.getCount() == 0; } /** * Cursor nulldur */ private boolean cursorIsNull(@Nullable final Cursor cursor) { return cursor == null; } /** * Silinecek şarkının dosyası hafızadan silinir. */ private boolean deleteSongFileInMemory(@NonNull Cursor songCursor) { final String dataUrl = cursorGetString(MediaColumns.DATA, songCursor); try { final File deleteFile = new File(dataUrl); return deleteFile(deleteFile); } catch (NullPointerException e) { return false; } } /** * Dosyanın silinmesi */ private boolean deleteFile(@NonNull final File deleteFile) { return deleteFile.delete(); } /** * Veri tabanında olan şarkının özelliklerine göre bilgileri string şeklinde * alınır. */ private String cursorGetString(final String column, @NonNull Cursor songCursor) { return songCursor.getString(songCursor.getColumnIndexOrThrow(column)); } /** * Veri tabanındaki şarkı bulunup silinir. */ private int deleteSongInDatabase(String selection) { return resolver.delete(songUri, selection, null); } // ------------------DELETE SONGS--------------------------------------- // ------------------ADD TO PLAYLIST--------------------------------------- /** * Şarkı eklenecek oynatma listesinin id si parametre olarak alınır.Buradan * geçici bir cursor üretilir. Cursor eklenecek şarkıların oynatma * listesindeki yerlerini belirler.Şarkıların bulunduğu cursor tek tek * dolaşılır. Dolaşılırken ContentValues tipindeki değişkenlere songId ve * songOrder eklenir.En sonunda ise bu değerler resolver yardımıyla veri * tabanına eklenir */ public void addToPlaylist(int playlistId, @NonNull Cursor songCursor) { final Cursor tempCursor = getPlaylistMemberCursor(getPlaylistMemberUri(playlistId)); ContentValues[] values = putSongsInContentValues(tempCursor, getContentValues(songCursor), songCursor); insertValuesInDatabase(playlistId, values); notifyChangeDatabase(Uri.parse("content://media")); tempCursor.close(); } /** * Id si olan bir oynatma listesinin adresi verilir. */ private Uri getPlaylistMemberUri(final int playlistId) { return MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId); } /** * Adresi belli olan bir oynatma listesinin cursoru oluşturulur. */ @Nullable private Cursor getPlaylistMemberCursor(@NonNull final Uri playlistMemberUri) { return resolver.query(playlistMemberUri, null, null, null, null); } /** * Şarkıların id leri ve sırası ContentValues değişkeni içine yerleştirlir. */ private ContentValues[] putSongsInContentValues(@NonNull Cursor tempCursor, ContentValues[] values, @Nullable Cursor songCursor) { if (songCursor != null && songCursor.getCount() != 0) { songCursor.moveToFirst(); int songOrder = tempCursor.getCount(); int i = 0; do { int songID = cursorGetInt(BaseColumns._ID, songCursor); values[i] = new ContentValues(); values[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, songOrder); values[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songID); songOrder++; i++; } while (songCursor.moveToNext()); } if (songCursor != null) { songCursor.close(); } return values; } /** * Veri tabanında olan şarkının özelliklerine göre bilgileri int şeklinde * alınır. */ private int cursorGetInt(final String column, @NonNull Cursor songCursor) { return songCursor.getInt(songCursor.getColumnIndexOrThrow(column)); } /** * ContentValues Array tipinde nesne üretilir. */ @NonNull private ContentValues[] getContentValues(@NonNull Cursor songCursor) { return new ContentValues[songCursor.getCount()]; } /** * Şarkıları oynatma listesine ve veritabanına eklenir. */ private int insertValuesInDatabase(int playlistId, @NonNull ContentValues[] values) { return resolver.bulkInsert(getPlaylistMemberUri(playlistId), values); } // ------------------ADD TO PLAYLIST--------------------------------------- // ------------------CREATE PLAYLIST--------------------------------------- /** * Öncelikle aynı isme sahip oynatma listeleri var mı kontrol edilir.Varsa * işlem başarısız olur.Yoksa oynatma listesinin adı ve değiştirilme * tarihleri ContentValues tipindeki değişkene koyulur.Bu değerler veri * tabanına eklenir. */ public boolean createPlaylist(String playlistName, @NonNull Uri playlistUri, @Nullable Cursor songCursor) { boolean exist = isExistSamePlaylist(playlistName, playlistUri); if (exist) { return false; } else { ContentValues values = putPlaylistFeaturesInContentValues(playlistName); int playlistId = insertPlaylistFeaturesInDatabase(values, playlistUri); notifyChangeDatabase(Uri.parse("content://media")); if (songCursor != null) { addToPlaylist(playlistId, songCursor); } return true; } } /** * Veri tabanında aynı isimli bir oynatma listesi var mı sorgulanır. Varsa * cursor boş değildir.Yani cursor de veri vardır. */ private boolean isExistSamePlaylist(String playlistName, @NonNull Uri playlistUri) { Cursor tempCursor = initCursor(playlistUri, null, PlaylistsColumns.NAME + " like ? ", new String[]{playlistName}, null); return isNotEmptyCursor(tempCursor); } /** * Cursor boş değilse */ private boolean isNotEmptyCursor(@NonNull Cursor cursor) { return cursor.getCount() != 0; } /** * Değerler veri tabanına eklenir. */ private int insertPlaylistFeaturesInDatabase(ContentValues values, @NonNull Uri playlistUri) { Uri newRowUri = resolver.insert(playlistUri, values); assert newRowUri != null; String[] path = newRowUri.toString().split("/"); return Integer.parseInt(path[path.length - 1]); } /** * Oynatma listesinin ismi ve eklenme , değiştirlme tarihleri values * değişkenenine koyulur. */ @NonNull private ContentValues putPlaylistFeaturesInContentValues(String playlistName) { ContentValues values = new ContentValues(); values.put(PlaylistsColumns.NAME, playlistName); return values; } /** * Veri tabanının değiştiği tüm adapterlara bildirlir. */ private void notifyChangeDatabase(@NonNull Uri uri) { resolver.notifyChange(uri, null); } // ------------------CREATE PLAYLIST--------------------------------------- // ------------------REMOVE PLAYLIST--------------------------------------- /** * Oynatma listelesi kaldırılır. */ public void removePlaylist(@NonNull Uri uri, String where, String[] selectionArgs) { resolver.delete(uri, where, selectionArgs); notifyChangeDatabase(Uri.parse("content://media")); } // ------------------REMOVE PLAYLIST--------------------------------------- // ------------------UPDATE PLAYLIST--------------------------------------- /** * Oynatma listesi güncellenir */ public void updatePlaylist(@NonNull Uri playlistUri, ContentValues values, String where, String[] selectionArgs) { resolver.update(playlistUri, values, where, selectionArgs); notifyChangeDatabase(Uri.parse("content://media")); } // ------------------UPDATE PLAYLIST--------------------------------------- // ------------------REMOVE SONG IN PLAYLIST------------------------------- /** * Oynatma listesindeki şarkı listeden kaldırılır. */ public void removeSongInPlaylist(@NonNull Uri uri, String where, String[] selectionArgs) { resolver.delete(uri, where, selectionArgs); notifyChangeDatabase(uri); } // ------------------REMOVE SONG IN PLAYLIST------------------------------- public void moveSongInPlaylist(long playlistId, int from, int to) { MediaStore.Audio.Playlists.Members.moveItem(resolver, playlistId, from, to); notifyChangeDatabase(Uri.parse("content://media")); } // ------------------DETAILS---------------------------------------------- @Nullable public abstract String details(); // ------------------DETAILS----------------------------------------------- // ------------------SEARCH---------------------------------------------- public void search(String search) { Intent searchIntent = new Intent(Intent.ACTION_WEB_SEARCH); searchIntent.putExtra(SearchManager.QUERY, search); context.startActivity(searchIntent); } // ------------------SEARCH---------------------------------------------- // ------------------SET AS PHONE RINGTONE------------------------------- public void setAsPhoneRingtone(@NonNull Cursor songCursor) { songCursor.moveToFirst(); String songID = cursorGetString(BaseColumns._ID, songCursor); String ringtoneUri = "content://media/external/audio/media/" + songID; RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, Uri.parse(ringtoneUri)); songCursor.close(); } // ------------------SET AS PHONE RINGTONE------------------------------- // ------------------------------SHARE---------------------------------- public void share(@NonNull Cursor songCursor) { songCursor.moveToFirst(); Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE); ArrayList<Uri> shareUris = new ArrayList<>(); do { String songID = cursorGetString(BaseColumns._ID, songCursor); Uri uri = Uri.parse("content://media/external/audio/media/" + songID); shareUris.add(uri); } while (songCursor.moveToNext()); shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, shareUris); shareIntent.setType("*/*"); context.startActivity(shareIntent); songCursor.close(); } // ------------------------------SHARE---------------------------------- }