package io.hefuyi.listener.util;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.audiofx.AudioEffect;
import android.net.Uri;
import android.os.Build;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import java.io.File;
import java.util.List;
import io.hefuyi.listener.MusicPlayer;
import io.hefuyi.listener.R;
import io.hefuyi.listener.RxBus;
import io.hefuyi.listener.dataloader.PlaylistLoader;
import io.hefuyi.listener.event.FavourateSongEvent;
import io.hefuyi.listener.event.MediaUpdateEvent;
import io.hefuyi.listener.event.PlaylistUpdateEvent;
import io.hefuyi.listener.event.RecentlyPlayEvent;
import io.hefuyi.listener.mvp.model.Playlist;
import io.hefuyi.listener.provider.FavoriteSong;
import io.hefuyi.listener.provider.RecentStore;
import io.hefuyi.listener.provider.SongPlayCount;
import io.hefuyi.listener.ui.dialogs.CreatePlaylistDialog;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
/**
* Created by hefuyi on 2016/11/4.
*/
public class ListenerUtil {
public static final String MUSIC_ONLY_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1"
+ " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''";
public static boolean isMarshmallow() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
public static boolean isLollipop() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
public static boolean isJellyBeanMR2() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
}
public static boolean isJellyBeanMR1() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
}
public static Uri getAlbumArtUri(long paramInt) {
return ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), paramInt);
}
public static final String makeLabel(final Context context, final int pluralInt,
final int number) {
return context.getResources().getQuantityString(pluralInt, number, number);
}
public static final String makeShortTimeString(final Context context, long secs) {
long hours, mins;
hours = secs / 3600;
secs %= 3600;
mins = secs / 60;
secs %= 60;
final String durationFormat = context.getResources().getString(
hours == 0 ? R.string.durationformatshort : R.string.durationformatlong);
return String.format(durationFormat, hours, mins, secs);
}
public static boolean hasEffectsPanel(final Activity activity) {
final PackageManager packageManager = activity.getPackageManager();
return packageManager.resolveActivity(createEffectsIntent(),
PackageManager.MATCH_DEFAULT_ONLY) != null;
}
public static Intent createEffectsIntent() {
final Intent effects = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
effects.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, MusicPlayer.getAudioSessionId());
return effects;
}
public static void showDeleteDialog(final Context context, final String name, final long[] list,
final MaterialDialog.SingleButtonCallback deleteCallback) {
new MaterialDialog.Builder(context)
.title(R.string.delete_song)
.content(context.getString(R.string.delete) +" "+ name + " ?")
.positiveText(R.string.delete)
.negativeText(R.string.cancel)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
ListenerUtil.deleteTracks(context, list);
deleteCallback.onClick(dialog, which);
RxBus.getInstance().post(new MediaUpdateEvent());
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
}
})
.show();
}
public static void showAddPlaylistDialog(final Context context, final long[] songIds) {
PlaylistLoader.getPlaylists(context, true)
.map(new Func1<List<Playlist>, Dialog>() {
@Override
public Dialog call(final List<Playlist> playlists) {
final CharSequence[] chars = new CharSequence[playlists.size() + 1];
chars[0] = context.getResources().getString(R.string.create_new_playlist);
for (int i = 0; i < playlists.size(); i++) {
chars[i + 1] = playlists.get(i).name;
}
return new MaterialDialog.Builder(context)
.title(R.string.add_to_playlist)
.items(chars)
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
if (which == 0) {
CreatePlaylistDialog.newInstance(songIds)
.show(((AppCompatActivity) context)
.getSupportFragmentManager(), context.getString(R.string.create_new_playlist));
return;
} else if (which == 1) {
//我喜欢
int num = FavoriteSong.getInstance(context).addFavoriteSong(songIds);
Toast.makeText(context, R.string.add_favorite_success, Toast.LENGTH_SHORT).show();
RxBus.getInstance().post(new FavourateSongEvent());
dialog.dismiss();
return;
}
MusicPlayer.addToPlaylist(context, songIds, playlists.get(which - 1).id);
RxBus.getInstance().post(new PlaylistUpdateEvent());
dialog.dismiss();
}
}).build();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Dialog>() {
@Override
public void call(Dialog dialog) {
dialog.show();
}
});
}
public static void showDeleteFromFavourate(final Context context, final long[] ids) {
new MaterialDialog.Builder(context)
.title(context.getResources().getString(R.string.delete_song_favourate) + "?")
.positiveText(R.string.delete)
.negativeText(R.string.cancel)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
FavoriteSong.getInstance(context).removeFavoriteSong(ids);
RxBus.getInstance().post(new FavourateSongEvent());
Toast.makeText(context, R.string.remove_favorite_success, Toast.LENGTH_SHORT).show();
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
}
})
.show();
}
public static void showDeleteFromRecentlyPlay(final Context context, final long[] ids) {
new MaterialDialog.Builder(context)
.title(context.getResources().getString(R.string.delete_song_recentlyplay) + "?")
.positiveText(R.string.delete)
.negativeText(R.string.cancel)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
RecentStore.getInstance(context).removeItem(ids);
RxBus.getInstance().post(new RecentlyPlayEvent());
Toast.makeText(context, R.string.remove_recentlyplay_success, Toast.LENGTH_SHORT).show();
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
}
})
.show();
}
public static void deleteTracks(final Context context, final long[] list) {
final String[] projection = new String[]{
BaseColumns._ID, MediaStore.MediaColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM_ID
};
final StringBuilder selection = new StringBuilder();
selection.append(BaseColumns._ID + " IN (");
for (int i = 0; i < list.length; i++) {
selection.append(list[i]);
if (i < list.length - 1) {
selection.append(",");
}
}
selection.append(")");
final Cursor c = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection.toString(),
null, null);
if (c != null) {
// Step 1: Remove selected tracks from the current playlist, as well
// as from the album art cache
c.moveToFirst();
while (!c.isAfterLast()) {
// Remove from current playlist
final long id = c.getLong(0);
MusicPlayer.removeTrack(id);
// Remove the track from the play count
SongPlayCount.getInstance(context).removeItem(id);
// Remove any items in the recents database
RecentStore.getInstance(context).removeItem(new long[]{id});
c.moveToNext();
}
// Step 2: Remove selected tracks from the database
context.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
selection.toString(), null);
// Step 3: Remove files from card
c.moveToFirst();
while (!c.isAfterLast()) {
final String name = c.getString(1);
final File f = new File(name);
try { // File.delete can throw a security exception
if (!f.delete()) {
// I'm not sure if we'd ever get here (deletion would
// have to fail, but no exception thrown)
Log.e("MusicUtils", "Failed to delete file " + name);
}
c.moveToNext();
} catch (final SecurityException ex) {
c.moveToNext();
}
}
c.close();
}
final String message = makeLabel(context, R.plurals.NNNtracksdeleted, list.length);
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
MusicPlayer.refresh();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static boolean isRtl(Resources res) {
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) &&
(res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
}
public enum IdType {
NA(0),
Artist(1),
Album(2),
Playlist(3),
Folder(4);
public final int mId;
IdType(final int id) {
mId = id;
}
public static IdType getTypeById(int id) {
for (IdType type : values()) {
if (type.mId == id) {
return type;
}
}
throw new IllegalArgumentException("Unrecognized id: " + id);
}
}
public enum PlaylistType {
LastAdded(-1, R.string.playlist_last_added),
RecentlyPlayed(-2, R.string.playlist_recently_played),
Favourate(-3, R.string.playlist_top_tracks);
public long mId;
public int mTitleId;
PlaylistType(long id, int titleId) {
mId = id;
mTitleId = titleId;
}
public static PlaylistType getTypeById(long id) {
for (PlaylistType type : PlaylistType.values()) {
if (type.mId == id) {
return type;
}
}
return null;
}
}
}