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----------------------------------
}