kotlin conversion

This commit is contained in:
h4h13 2018-11-30 06:36:16 +05:30
parent 8e6ab40d93
commit b2c15ef186
316 changed files with 13055 additions and 22983 deletions

View file

@ -1,171 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.media.audiofx.BassBoost;
import android.media.audiofx.Equalizer;
import android.media.audiofx.Virtualizer;
import android.util.Log;
import code.name.monkey.retromusic.interfaces.EqualizerInterface;
/**
* @author Hemanth S (h4h13).
*/
public class EqualizerHelper implements EqualizerInterface {
private static final String TAG = "EqualizerHelper";
private static volatile EqualizerHelper ourInstance;
private Equalizer mEqualizer;
private BassBoost mBassBoost;
private Virtualizer mVirtualizer;
private int mMaxLevel, mMinLevel;
private boolean isRunning = false;
private EqualizerHelper() {
//Prevent form the reflection api.
if (ourInstance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}
int i = MusicPlayerRemote.getAudioSessionId();
mEqualizer = new Equalizer(100, i);
if (mEqualizer == null) {
Log.i(TAG, "onCreate: Equalizer is null");
return;
}
mEqualizer.setEnabled(true);
mBassBoost = new BassBoost(100, i);
if (mBassBoost == null) {
Log.i(TAG, "onCreate: BassBoost is null");
return;
}
mVirtualizer = new Virtualizer(100, i);
if (mVirtualizer == null) {
Log.i(TAG, "onCreate: Virtualizer is null");
return;
}
mMaxLevel = (int) mEqualizer.getBandLevelRange()[1];
mMinLevel = (int) mEqualizer.getBandLevelRange()[0];
Log.i(TAG, "onCreate: " + mMaxLevel + " " + mMinLevel);
isRunning = true;
}
public static EqualizerHelper getInstance() {
//Double check locking pattern
if (ourInstance == null) {//Check for the first time
synchronized (EqualizerHelper.class) {//Check for the second time.
//if there is no instance available... create new one
if (ourInstance == null) {
ourInstance = new EqualizerHelper();
}
}
}
return ourInstance;
}
//Make singleton from serialize and deserialize operation.
protected EqualizerHelper readResolve() {
return getInstance();
}
@Override
public Equalizer getEqualizer() {
return mEqualizer;
}
@Override
public BassBoost getBassBoost() {
return mBassBoost;
}
@Override
public Virtualizer getVirtualizer() {
return mVirtualizer;
}
@Override
public int getBandLevelLow() {
return mMinLevel;
}
@Override
public int getBandLevelHigh() {
return mMaxLevel;
}
@Override
public int getNumberOfBands() {
return (int) mEqualizer.getNumberOfBands();
}
@Override
public int getCenterFreq(int band) {
return (int) mEqualizer.getCenterFreq((short) band);
}
@Override
public int getBandLevel(int band) {
return (int) mEqualizer.getBandLevel((short) band);
}
@Override
public void setBandLevel(int band, int level) {
mEqualizer.setBandLevel((short) band, (short) level);
}
@Override
public boolean isBassBoostEnabled() {
return mBassBoost.getEnabled();
}
@Override
public void setBassBoostEnabled(boolean isEnabled) {
mBassBoost.setEnabled(isEnabled);
}
@Override
public int getBassBoostStrength() {
return (int) mBassBoost.getRoundedStrength();
}
@Override
public void setBassBoostStrength(int strength) {
mBassBoost.setStrength((short) strength);
}
@Override
public boolean isVirtualizerEnabled() {
return mVirtualizer.getEnabled();
}
@Override
public void setVirtualizerEnabled(boolean isEnabled) {
mVirtualizer.setEnabled(isEnabled);
}
@Override
public int getVirtualizerStrength() {
return mVirtualizer.getRoundedStrength();
}
@Override
public void setVirtualizerStrength(int strength) {
mVirtualizer.setStrength((short) strength);
}
@Override
public boolean isRunning() {
return isRunning;
}
}

View file

@ -0,0 +1,109 @@
package code.name.monkey.retromusic.helper
import android.media.audiofx.BassBoost
import android.media.audiofx.Equalizer
import android.media.audiofx.Virtualizer
import android.util.Log
import code.name.monkey.retromusic.interfaces.EqualizerInterface
/**
* @author Hemanth S (h4h13).
*/
class EqualizerHelper private constructor() : EqualizerInterface {
override val equalizer: Equalizer
override val bassBoost: BassBoost
override val virtualizer: Virtualizer
override val bandLevelHigh: Int
override val bandLevelLow: Int
override var isRunning = false
override val numberOfBands: Int
get() = equalizer.numberOfBands.toInt()
override var isBassBoostEnabled: Boolean
get() = bassBoost.enabled
set(isEnabled) {
bassBoost.enabled = isEnabled
}
override var bassBoostStrength: Int
get() = bassBoost.roundedStrength.toInt()
set(strength) = bassBoost.setStrength(strength.toShort())
override var isVirtualizerEnabled: Boolean
get() = virtualizer.enabled
set(isEnabled) {
virtualizer.enabled = isEnabled
}
override var virtualizerStrength: Int
get() = virtualizer.roundedStrength.toInt()
set(strength) = virtualizer.setStrength(strength.toShort())
init {
//Prevent form the reflection api.
if (ourInstance != null) {
throw RuntimeException("Use getInstance() method to get the single instance of this class.")
}
val i = MusicPlayerRemote.audioSessionId
equalizer = Equalizer(100, i)
equalizer.enabled = true
bassBoost = BassBoost(100, i)
virtualizer = Virtualizer(100, i)
bandLevelHigh = equalizer.bandLevelRange[1].toInt()
bandLevelLow = equalizer.bandLevelRange[0].toInt()
Log.i(TAG, "onCreate: $bandLevelHigh $bandLevelLow")
isRunning = true
}
//Make singleton from serialize and deserialize operation.
protected fun readResolve(): EqualizerHelper? {
return instance
}
override fun getCenterFreq(band: Int): Int {
return equalizer.getCenterFreq(band.toShort())
}
override fun getBandLevel(band: Int): Int {
return equalizer.getBandLevel(band.toShort()).toInt()
}
override fun setBandLevel(band: Int, level: Int) {
equalizer.setBandLevel(band.toShort(), level.toShort())
}
companion object {
private val TAG = "EqualizerHelper"
@Volatile
private var ourInstance: EqualizerHelper? = null
//Double check locking pattern
//Check for the first time
//Check for the second time.
//if there is no instance available... create new one
val instance: EqualizerHelper?
get() {
if (ourInstance == null) {
synchronized(EqualizerHelper::class.java) {
if (ourInstance == null) {
ourInstance = EqualizerHelper()
}
}
}
return ourInstance
}
}
}

View file

@ -1,36 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.content.Context;
import android.view.ViewGroup;
import code.name.monkey.retromusic.R;
public class HorizontalAdapterHelper {
public static final int LAYOUT_RES = R.layout.item_image;
public static final int TYPE_FIRST = 1;
public static final int TYPE_MIDDLE = 2;
public static final int TYPE_LAST = 3;
public static void applyMarginToLayoutParams(Context context,
ViewGroup.MarginLayoutParams layoutParams, int viewType) {
int listMargin = context.getResources()
.getDimensionPixelSize(R.dimen.now_playing_top_margin);
if (viewType == TYPE_FIRST) {
layoutParams.leftMargin = listMargin;
} else if (viewType == TYPE_LAST) {
layoutParams.rightMargin = listMargin;
}
}
public static int getItemViewtype(int position, int itemCount) {
if (position == 0) {
return TYPE_FIRST;
} else if (position == itemCount - 1) {
return TYPE_LAST;
} else {
return TYPE_MIDDLE;
}
}
}

View file

@ -0,0 +1,36 @@
package code.name.monkey.retromusic.helper
import android.content.Context
import android.view.ViewGroup
import code.name.monkey.retromusic.R
object HorizontalAdapterHelper {
val LAYOUT_RES = R.layout.item_image
val TYPE_FIRST = 1
val TYPE_MIDDLE = 2
val TYPE_LAST = 3
fun applyMarginToLayoutParams(context: Context,
layoutParams: ViewGroup.MarginLayoutParams, viewType: Int) {
val listMargin = context.resources
.getDimensionPixelSize(R.dimen.now_playing_top_margin)
if (viewType == TYPE_FIRST) {
layoutParams.leftMargin = listMargin
} else if (viewType == TYPE_LAST) {
layoutParams.rightMargin = listMargin
}
}
fun getItemViewtype(position: Int, itemCount: Int): Int {
return if (position == 0) {
TYPE_FIRST
} else if (position == itemCount - 1) {
TYPE_LAST
} else {
TYPE_MIDDLE
}
}
}

View file

@ -1,8 +0,0 @@
package code.name.monkey.retromusic.helper;
public interface M3UConstants {
String EXTENSION = "m3u";
String HEADER = "#EXTM3U";
String ENTRY = "#EXTINF:";
String DURATION_SEPARATOR = ",";
}

View file

@ -0,0 +1,10 @@
package code.name.monkey.retromusic.helper
interface M3UConstants {
companion object {
val EXTENSION = "m3u"
val HEADER = "#EXTM3U"
val ENTRY = "#EXTINF:"
val DURATION_SEPARATOR = ","
}
}

View file

@ -1,58 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.content.Context;
import androidx.annotation.NonNull;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
public class M3UWriter implements M3UConstants {
public static final String TAG = M3UWriter.class.getSimpleName();
public static Observable<File> write(@NonNull Context context,
@NonNull File dir, @NonNull Playlist playlist) {
if (!dir.exists()) //noinspection ResultOfMethodCallIgnored
dir.mkdirs();
File file = new File(dir, playlist.name.concat("." + EXTENSION));
if (playlist instanceof AbsCustomPlaylist) {
return Observable.create(e -> {
((AbsCustomPlaylist) playlist).getSongs(context).subscribe(songs -> {
saveSongsToFile(file, e, songs);
});
});
} else
return Observable.create(e ->
PlaylistSongsLoader.getPlaylistSongList(context, playlist.id)
.subscribe(songs -> {
saveSongsToFile(file, e, songs);
}));
}
private static void saveSongsToFile(File file, ObservableEmitter<File> e, ArrayList<Song> songs) throws IOException {
if (songs.size() > 0) {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(HEADER);
for (Song song : songs) {
bw.newLine();
bw.write(ENTRY + song.duration + DURATION_SEPARATOR + song.artistName + " - " + song.title);
bw.newLine();
bw.write(song.data);
}
bw.close();
}
e.onNext(file);
e.onComplete();
}
}

View file

@ -0,0 +1,53 @@
package code.name.monkey.retromusic.helper
import android.content.Context
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.util.ArrayList
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
class M3UWriter : M3UConstants {
companion object {
val TAG: String = M3UWriter::class.java.simpleName
fun write(context: Context,
dir: File, playlist: Playlist): Observable<File> {
if (!dir.exists())
dir.mkdirs()
val file = File(dir, playlist.name + ("." + M3UConstants.EXTENSION))
return if (playlist is AbsCustomPlaylist) {
Observable.create { e -> playlist.getSongs(context).subscribe { songs -> saveSongsToFile(file, e, songs) } }
} else
Observable.create { e -> PlaylistSongsLoader.getPlaylistSongList(context, playlist.id).subscribe { songs -> saveSongsToFile(file, e, songs) } }
}
@Throws(IOException::class)
private fun saveSongsToFile(file: File, e: ObservableEmitter<File>, songs: ArrayList<Song>) {
if (songs.size > 0) {
val bw = BufferedWriter(FileWriter(file))
bw.write(M3UConstants.HEADER)
for (song in songs) {
bw.newLine()
bw.write(M3UConstants.ENTRY + song.duration + M3UConstants.DURATION_SEPARATOR + song.artistName + " - " + song.title)
bw.newLine()
bw.write(song.data)
}
bw.close()
}
e.onNext(file)
e.onComplete()
}
}
}

View file

@ -1,496 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import java.util.WeakHashMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.service.MusicService;
import code.name.monkey.retromusic.util.PreferenceUtil;
import io.reactivex.schedulers.Schedulers;
public class MusicPlayerRemote {
public static final String TAG = MusicPlayerRemote.class.getSimpleName();
private static final WeakHashMap<Context, ServiceBinder> mConnectionMap = new WeakHashMap<>();
@Nullable
public static MusicService musicService;
private static int playbackLocation = PlaybackLocation.LOCAL;
private static CastSession getCastSession() {
CastSession castSession = CastContext.getSharedInstance(RetroApplication.getInstance()).getSessionManager().getCurrentCastSession();
if (castSession != null) {
playbackLocation = PlaybackLocation.REMOTE;
} else {
playbackLocation = PlaybackLocation.LOCAL;
}
return castSession;
}
public static ServiceToken bindToService(@NonNull final Context context,
final ServiceConnection callback) {
Activity realActivity = ((Activity) context).getParent();
if (realActivity == null) {
realActivity = (Activity) context;
}
final ContextWrapper contextWrapper = new ContextWrapper(realActivity);
contextWrapper.startService(new Intent(contextWrapper, MusicService.class));
final ServiceBinder binder = new ServiceBinder(callback);
if (contextWrapper.bindService(new Intent().setClass(contextWrapper, MusicService.class), binder, Context.BIND_AUTO_CREATE)) {
mConnectionMap.put(contextWrapper, binder);
return new ServiceToken(contextWrapper);
}
return null;
}
public static void unbindFromService(@Nullable final ServiceToken token) {
if (token == null) {
return;
}
final ContextWrapper mContextWrapper = token.mWrappedContext;
final ServiceBinder mBinder = mConnectionMap.remove(mContextWrapper);
if (mBinder == null) {
return;
}
mContextWrapper.unbindService(mBinder);
if (mConnectionMap.isEmpty()) {
musicService = null;
}
}
@Nullable
private static String getFilePathFromUri(Context context, Uri uri) {
final String column = "_data";
final String[] projection = {
column
};
try (Cursor cursor = context.getContentResolver().query(uri, projection, null, null,
null)) {
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
/**
* Async
*/
public static void playSongAt(final int position) {
if (musicService != null) {
musicService.playSongAt(position);
}
}
public static void pauseSong() {
if (musicService != null) {
musicService.pause();
}
}
/**
* Async
*/
public static void playNextSong() {
if (musicService != null) {
musicService.playNextSong(true);
}
}
/**
* Async
*/
public static void playPreviousSong() {
if (musicService != null) {
musicService.playPreviousSong(true);
}
}
/**
* Async
*/
public static void back() {
if (musicService != null) {
musicService.back(true);
}
}
public static boolean isPlaying() {
return musicService != null && musicService.isPlaying();
}
public static void resumePlaying() {
if (musicService != null) {
musicService.play();
}
}
/**
* Async
*/
public static void openQueue(final ArrayList<Song> queue, final int startPosition, final boolean startPlaying) {
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
musicService.openQueue(queue, startPosition, startPlaying);
if (PreferenceUtil.getInstance().isShuffleModeOn())
setShuffleMode(MusicService.SHUFFLE_MODE_NONE);
}
}
/**
* Async
*/
public static void openAndShuffleQueue(final ArrayList<Song> queue, boolean startPlaying) {
int startPosition = 0;
if (!queue.isEmpty()) {
startPosition = new Random().nextInt(queue.size());
}
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
openQueue(queue, startPosition, startPlaying);
setShuffleMode(MusicService.SHUFFLE_MODE_SHUFFLE);
}
}
private static boolean tryToHandleOpenPlayingQueue(final ArrayList<Song> queue, final int startPosition, final boolean startPlaying) {
if (getPlayingQueue() == queue) {
if (startPlaying) {
playSongAt(startPosition);
} else {
setPosition(startPosition);
}
return true;
}
return false;
}
public static Song getCurrentSong() {
if (musicService != null) {
return musicService.getCurrentSong();
}
return Song.EMPTY_SONG;
}
public static int getPosition() {
if (musicService != null) {
return musicService.getPosition();
}
return -1;
}
/**
* Async
*/
public static void setPosition(final int position) {
if (musicService != null) {
musicService.setPosition(position);
}
}
public static ArrayList<Song> getPlayingQueue() {
if (musicService != null) {
return musicService.getPlayingQueue();
}
return new ArrayList<>();
}
public static int getSongProgressMillis() {
if (musicService != null) {
return musicService.getSongProgressMillis();
}
return -1;
}
public static int getSongDurationMillis() {
if (musicService != null) {
return musicService.getSongDurationMillis();
}
return -1;
}
public static long getQueueDurationMillis(int position) {
if (musicService != null) {
return musicService.getQueueDurationMillis(position);
}
return -1;
}
public static int seekTo(int millis) {
if (musicService != null) {
return musicService.seek(millis);
}
return -1;
}
public static int getRepeatMode() {
if (musicService != null) {
return musicService.getRepeatMode();
}
return MusicService.REPEAT_MODE_NONE;
}
public static int getShuffleMode() {
if (musicService != null) {
return musicService.getShuffleMode();
}
return MusicService.SHUFFLE_MODE_NONE;
}
public static boolean cycleRepeatMode() {
if (musicService != null) {
musicService.cycleRepeatMode();
return true;
}
return false;
}
public static boolean toggleShuffleMode() {
if (musicService != null) {
musicService.toggleShuffle();
return true;
}
return false;
}
public static boolean setShuffleMode(final int shuffleMode) {
if (musicService != null) {
musicService.setShuffleMode(shuffleMode);
return true;
}
return false;
}
public static boolean playNext(Song song) {
if (musicService != null) {
if (getPlayingQueue().size() > 0) {
musicService.addSong(getPosition() + 1, song);
} else {
ArrayList<Song> queue = new ArrayList<>();
queue.add(song);
openQueue(queue, 0, false);
}
Toast.makeText(musicService, musicService.getResources().getString(R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
public static boolean playNext(@NonNull ArrayList<Song> songs) {
if (musicService != null) {
if (getPlayingQueue().size() > 0) {
musicService.addSongs(getPosition() + 1, songs);
} else {
openQueue(songs, 0, false);
}
final String toast = songs.size() == 1 ? musicService.getResources().getString(R.string.added_title_to_playing_queue) : musicService.getResources().getString(R.string.added_x_titles_to_playing_queue, songs.size());
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
public static boolean enqueue(Song song) {
if (musicService != null) {
if (getPlayingQueue().size() > 0) {
musicService.addSong(song);
} else {
ArrayList<Song> queue = new ArrayList<>();
queue.add(song);
openQueue(queue, 0, false);
}
Toast.makeText(musicService, musicService.getResources().getString(R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
public static boolean enqueue(@NonNull ArrayList<Song> songs) {
if (musicService != null) {
if (getPlayingQueue().size() > 0) {
musicService.addSongs(songs);
} else {
openQueue(songs, 0, false);
}
final String toast = songs.size() == 1 ? musicService.getResources().getString(R.string.added_title_to_playing_queue) : musicService.getResources().getString(R.string.added_x_titles_to_playing_queue, songs.size());
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
public static boolean removeFromQueue(@NonNull Song song) {
if (musicService != null) {
musicService.removeSong(song);
return true;
}
return false;
}
public static boolean removeFromQueue(int position) {
if (musicService != null && position >= 0 && position < getPlayingQueue().size()) {
musicService.removeSong(position);
return true;
}
return false;
}
public static boolean moveSong(int from, int to) {
if (musicService != null && from >= 0 && to >= 0 && from < getPlayingQueue().size() && to < getPlayingQueue().size()) {
musicService.moveSong(from, to);
return true;
}
return false;
}
public static boolean clearQueue() {
if (musicService != null) {
musicService.clearQueue();
return true;
}
return false;
}
public static int getAudioSessionId() {
if (musicService != null) {
return musicService.getAudioSessionId();
}
return -1;
}
public static void playFromUri(Uri uri) {
if (musicService != null) {
ArrayList<Song> songs = null;
if (uri.getScheme() != null && uri.getAuthority() != null) {
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
String songId = null;
if (uri.getAuthority().equals("com.android.providers.media.documents")) {
songId = getSongIdFromMediaProvider(uri);
} else if (uri.getAuthority().equals("media")) {
songId = uri.getLastPathSegment();
}
if (songId != null) {
/* songs = SongLoader.getSongs(SongLoader.makeSongCursor(
musicService,
MediaStore.Audio.AudioColumns._ID + "=?",
new String[]{songId}
));*/
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
musicService,
MediaStore.Audio.AudioColumns._ID + "=?",
new String[]{songId}))
.subscribeOn(Schedulers.io()).blockingFirst();
}
}
}
if (songs == null) {
File songFile = null;
if (uri.getAuthority() != null && uri.getAuthority().equals("com.android.externalstorage.documents")) {
songFile = new File(Environment.getExternalStorageDirectory(), uri.getPath().split(":", 2)[1]);
}
if (songFile == null) {
String path = getFilePathFromUri(musicService, uri);
if (path != null)
songFile = new File(path);
}
if (songFile == null && uri.getPath() != null) {
songFile = new File(uri.getPath());
}
if (songFile != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(
musicService,
MediaStore.Audio.AudioColumns.DATA + "=?",
new String[]{songFile.getAbsolutePath()}
)).blockingFirst();
}
}
if (songs != null && !songs.isEmpty()) {
openQueue(songs, 0, true);
} else {
//TODO the file is not listed in the media store
}
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private static String getSongIdFromMediaProvider(Uri uri) {
return DocumentsContract.getDocumentId(uri).split(":")[1];
}
public static boolean isServiceConnected() {
return musicService != null;
}
@interface PlaybackLocation {
int REMOTE = 0;
int LOCAL = 1;
}
public static final class ServiceBinder implements ServiceConnection {
private final ServiceConnection mCallback;
ServiceBinder(final ServiceConnection callback) {
mCallback = callback;
}
@Override
public void onServiceConnected(final ComponentName className, final IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
musicService = binder.getService();
if (mCallback != null) {
mCallback.onServiceConnected(className, service);
}
}
@Override
public void onServiceDisconnected(final ComponentName className) {
if (mCallback != null) {
mCallback.onServiceDisconnected(className);
}
musicService = null;
}
}
public static final class ServiceToken {
ContextWrapper mWrappedContext;
ServiceToken(final ContextWrapper context) {
mWrappedContext = context;
}
}
}

View file

@ -0,0 +1,440 @@
package code.name.monkey.retromusic.helper
import android.annotation.TargetApi
import android.app.Activity
import android.content.*
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.IBinder
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroApplication
import code.name.monkey.retromusic.loaders.SongLoader
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.PreferenceUtil
import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastSession
import io.reactivex.schedulers.Schedulers
import java.io.File
import java.util.*
object MusicPlayerRemote {
val TAG = MusicPlayerRemote::class.java.simpleName
private val mConnectionMap = WeakHashMap<Context, ServiceBinder>()
var musicService: MusicService? = null
private var playbackLocation = PlaybackLocation.LOCAL
private val castSession: CastSession?
get() {
val castSession = CastContext.getSharedInstance(RetroApplication.instance).sessionManager.currentCastSession
if (castSession != null) {
playbackLocation = PlaybackLocation.REMOTE
} else {
playbackLocation = PlaybackLocation.LOCAL
}
return castSession
}
val isPlaying: Boolean
get() = musicService != null && musicService!!.isPlaying
val currentSong: Song
get() = if (musicService != null) {
musicService!!.currentSong
} else Song.EMPTY_SONG
/**
* Async
*/
var position: Int
get() = if (musicService != null) {
musicService!!.position
} else -1
set(position) {
if (musicService != null) {
musicService!!.position = position
}
}
val playingQueue: ArrayList<Song>
get() = if (musicService != null) {
musicService!!.playingQueue
} else ArrayList()
val songProgressMillis: Int
get() = if (musicService != null) {
musicService!!.songProgressMillis
} else -1
val songDurationMillis: Int
get() = if (musicService != null) {
musicService!!.songDurationMillis
} else -1
val repeatMode: Int
get() = if (musicService != null) {
musicService!!.repeatMode
} else MusicService.REPEAT_MODE_NONE
val shuffleMode: Int
get() = if (musicService != null) {
musicService!!.shuffleMode
} else MusicService.SHUFFLE_MODE_NONE
val audioSessionId: Int
get() = if (musicService != null) {
musicService!!.audioSessionId
} else -1
val isServiceConnected: Boolean
get() = musicService != null
fun bindToService(context: Context,
callback: ServiceConnection): ServiceToken? {
var realActivity: Activity? = (context as Activity).parent
if (realActivity == null) {
realActivity = context
}
val contextWrapper = ContextWrapper(realActivity)
contextWrapper.startService(Intent(contextWrapper, MusicService::class.java))
val binder = ServiceBinder(callback)
if (contextWrapper.bindService(Intent().setClass(contextWrapper, MusicService::class.java), binder, Context.BIND_AUTO_CREATE)) {
mConnectionMap[contextWrapper] = binder
return ServiceToken(contextWrapper)
}
return null
}
fun unbindFromService(token: ServiceToken?) {
if (token == null) {
return
}
val mContextWrapper = token.mWrappedContext
val mBinder = mConnectionMap.remove(mContextWrapper) ?: return
mContextWrapper.unbindService(mBinder)
if (mConnectionMap.isEmpty()) {
musicService = null
}
}
private fun getFilePathFromUri(context: Context, uri: Uri): String? {
val column = "_data"
val projection = arrayOf(column)
try {
context.contentResolver.query(uri, projection, null, null, null)!!.use { cursor ->
if (cursor.moveToFirst()) {
val column_index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(column_index)
}
}
} catch (e: Exception) {
Log.e(TAG, e.message)
}
return null
}
/**
* Async
*/
fun playSongAt(position: Int) {
if (musicService != null) {
musicService!!.playSongAt(position)
}
}
fun pauseSong() {
if (musicService != null) {
musicService!!.pause()
}
}
/**
* Async
*/
fun playNextSong() {
if (musicService != null) {
musicService!!.playNextSong(true)
}
}
/**
* Async
*/
fun playPreviousSong() {
if (musicService != null) {
musicService!!.playPreviousSong(true)
}
}
/**
* Async
*/
fun back() {
if (musicService != null) {
musicService!!.back(true)
}
}
fun resumePlaying() {
if (musicService != null) {
musicService!!.play()
}
}
/**
* Async
*/
fun openQueue(queue: ArrayList<Song>, startPosition: Int, startPlaying: Boolean) {
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
musicService!!.openQueue(queue, startPosition, startPlaying)
if (PreferenceUtil.getInstance().isShuffleModeOn)
setShuffleMode(MusicService.SHUFFLE_MODE_NONE)
}
}
/**
* Async
*/
fun openAndShuffleQueue(queue: ArrayList<Song>, startPlaying: Boolean) {
var startPosition = 0
if (!queue.isEmpty()) {
startPosition = Random().nextInt(queue.size)
}
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
openQueue(queue, startPosition, startPlaying)
setShuffleMode(MusicService.SHUFFLE_MODE_SHUFFLE)
}
}
private fun tryToHandleOpenPlayingQueue(queue: ArrayList<Song>, startPosition: Int, startPlaying: Boolean): Boolean {
if (playingQueue === queue) {
if (startPlaying) {
playSongAt(startPosition)
} else {
position = startPosition
}
return true
}
return false
}
fun getQueueDurationMillis(position: Int): Long {
return if (musicService != null) {
musicService!!.getQueueDurationMillis(position)
} else -1
}
fun seekTo(millis: Int): Int {
return if (musicService != null) {
musicService!!.seek(millis)
} else -1
}
fun cycleRepeatMode(): Boolean {
if (musicService != null) {
musicService!!.cycleRepeatMode()
return true
}
return false
}
fun toggleShuffleMode(): Boolean {
if (musicService != null) {
musicService!!.toggleShuffle()
return true
}
return false
}
fun setShuffleMode(shuffleMode: Int): Boolean {
if (musicService != null) {
musicService!!.shuffleMode = shuffleMode
return true
}
return false
}
fun playNext(song: Song): Boolean {
if (musicService != null) {
if (playingQueue.size > 0) {
musicService!!.addSong(position + 1, song)
} else {
val queue = ArrayList<Song>()
queue.add(song)
openQueue(queue, 0, false)
}
Toast.makeText(musicService, musicService!!.resources.getString(R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show()
return true
}
return false
}
fun playNext(songs: ArrayList<Song>): Boolean {
if (musicService != null) {
if (playingQueue.size > 0) {
musicService!!.addSongs(position + 1, songs)
} else {
openQueue(songs, 0, false)
}
val toast = if (songs.size == 1) musicService!!.resources.getString(R.string.added_title_to_playing_queue) else musicService!!.resources.getString(R.string.added_x_titles_to_playing_queue, songs.size)
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show()
return true
}
return false
}
fun enqueue(song: Song): Boolean {
if (musicService != null) {
if (playingQueue.size > 0) {
musicService!!.addSong(song)
} else {
val queue = ArrayList<Song>()
queue.add(song)
openQueue(queue, 0, false)
}
Toast.makeText(musicService, musicService!!.resources.getString(R.string.added_title_to_playing_queue), Toast.LENGTH_SHORT).show()
return true
}
return false
}
fun enqueue(songs: ArrayList<Song>): Boolean {
if (musicService != null) {
if (playingQueue.size > 0) {
musicService!!.addSongs(songs)
} else {
openQueue(songs, 0, false)
}
val toast = if (songs.size == 1) musicService!!.resources.getString(R.string.added_title_to_playing_queue) else musicService!!.resources.getString(R.string.added_x_titles_to_playing_queue, songs.size)
Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show()
return true
}
return false
}
fun removeFromQueue(song: Song): Boolean {
if (musicService != null) {
musicService!!.removeSong(song)
return true
}
return false
}
fun removeFromQueue(position: Int): Boolean {
if (musicService != null && position >= 0 && position < playingQueue.size) {
musicService!!.removeSong(position)
return true
}
return false
}
fun moveSong(from: Int, to: Int): Boolean {
if (musicService != null && from >= 0 && to >= 0 && from < playingQueue.size && to < playingQueue.size) {
musicService!!.moveSong(from, to)
return true
}
return false
}
fun clearQueue(): Boolean {
if (musicService != null) {
musicService!!.clearQueue()
return true
}
return false
}
fun playFromUri(uri: Uri) {
if (musicService != null) {
var songs: ArrayList<Song>? = null
if (uri.scheme != null && uri.authority != null) {
if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
var songId: String? = null
if (uri.authority == "com.android.providers.media.documents") {
songId = getSongIdFromMediaProvider(uri)
} else if (uri.authority == "media") {
songId = uri.lastPathSegment
}
if (songId != null) {
/* songs = SongLoader.getSongs(SongLoader.makeSongCursor(
musicService,
MediaStore.Audio.AudioColumns._ID + "=?",
new String[]{songId}
));*/
songs = SongLoader.getSongs(SongLoader.makeSongCursor(
musicService!!,
MediaStore.Audio.AudioColumns._ID + "=?",
arrayOf(songId)))
.subscribeOn(Schedulers.io()).blockingFirst()
}
}
}
if (songs == null) {
var songFile: File? = null
if (uri.authority != null && uri.authority == "com.android.externalstorage.documents") {
songFile = File(Environment.getExternalStorageDirectory(), uri.path!!.split(":".toRegex(), 2).toTypedArray()[1])
}
if (songFile == null) {
val path = getFilePathFromUri(musicService!!, uri)
if (path != null)
songFile = File(path)
}
if (songFile == null && uri.path != null) {
songFile = File(uri.path)
}
if (songFile != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(musicService!!, MediaStore.Audio.AudioColumns.DATA + "=?", arrayOf(songFile.absolutePath)
)).blockingFirst()
}
}
if (songs != null && !songs.isEmpty()) {
openQueue(songs, 0, true)
} else {
//TODO the file is not listed in the media store
}
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private fun getSongIdFromMediaProvider(uri: Uri): String {
return DocumentsContract.getDocumentId(uri).split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
}
internal annotation class PlaybackLocation {
companion object {
val REMOTE = 0
val LOCAL = 1
}
}
class ServiceBinder internal constructor(private val mCallback: ServiceConnection?) : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as MusicService.MusicBinder
musicService = binder.service
mCallback?.onServiceConnected(className, service)
}
override fun onServiceDisconnected(className: ComponentName) {
mCallback?.onServiceDisconnected(className)
musicService = null
}
}
class ServiceToken internal constructor(internal var mWrappedContext: ContextWrapper)
}

View file

@ -1,71 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.NonNull;
public class MusicProgressViewUpdateHelper extends Handler {
private static final int CMD_REFRESH_PROGRESS_VIEWS = 1;
private static final int MIN_INTERVAL = 20;
private static final int UPDATE_INTERVAL_PLAYING = 1000;
private static final int UPDATE_INTERVAL_PAUSED = 500;
private Callback callback;
private int intervalPlaying;
private int intervalPaused;
public void start() {
queueNextRefresh(1);
}
public void stop() {
removeMessages(CMD_REFRESH_PROGRESS_VIEWS);
}
public MusicProgressViewUpdateHelper(Callback callback) {
this.callback = callback;
this.intervalPlaying = UPDATE_INTERVAL_PLAYING;
this.intervalPaused = UPDATE_INTERVAL_PAUSED;
}
public MusicProgressViewUpdateHelper(Callback callback, int intervalPlaying, int intervalPaused) {
this.callback = callback;
this.intervalPlaying = intervalPlaying;
this.intervalPaused = intervalPaused;
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == CMD_REFRESH_PROGRESS_VIEWS) {
queueNextRefresh(refreshProgressViews());
}
}
private int refreshProgressViews() {
final int progressMillis = MusicPlayerRemote.getSongProgressMillis();
final int totalMillis = MusicPlayerRemote.getSongDurationMillis();
callback.onUpdateProgressViews(progressMillis, totalMillis);
if (!MusicPlayerRemote.isPlaying()) {
return intervalPaused;
}
final int remainingMillis = intervalPlaying - progressMillis % intervalPlaying;
return Math.max(MIN_INTERVAL, remainingMillis);
}
private void queueNextRefresh(final long delay) {
final Message message = obtainMessage(CMD_REFRESH_PROGRESS_VIEWS);
removeMessages(CMD_REFRESH_PROGRESS_VIEWS);
sendMessageDelayed(message, delay);
}
public interface Callback {
void onUpdateProgressViews(int progress, int total);
}
}

View file

@ -0,0 +1,72 @@
package code.name.monkey.retromusic.helper
import android.os.Handler
import android.os.Message
class MusicProgressViewUpdateHelper : Handler {
private var callback: Callback? = null
private var intervalPlaying: Int = 0
private var intervalPaused: Int = 0
fun start() {
queueNextRefresh(1)
}
fun stop() {
removeMessages(CMD_REFRESH_PROGRESS_VIEWS)
}
constructor(callback: Callback) {
this.callback = callback
this.intervalPlaying = UPDATE_INTERVAL_PLAYING
this.intervalPaused = UPDATE_INTERVAL_PAUSED
}
constructor(callback: Callback, intervalPlaying: Int, intervalPaused: Int) {
this.callback = callback
this.intervalPlaying = intervalPlaying
this.intervalPaused = intervalPaused
}
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if (msg.what == CMD_REFRESH_PROGRESS_VIEWS) {
queueNextRefresh(refreshProgressViews().toLong())
}
}
private fun refreshProgressViews(): Int {
val progressMillis = MusicPlayerRemote.songProgressMillis
val totalMillis = MusicPlayerRemote.songDurationMillis
callback!!.onUpdateProgressViews(progressMillis, totalMillis)
if (!MusicPlayerRemote.isPlaying) {
return intervalPaused
}
val remainingMillis = intervalPlaying - progressMillis % intervalPlaying
return Math.max(MIN_INTERVAL, remainingMillis)
}
private fun queueNextRefresh(delay: Long) {
val message = obtainMessage(CMD_REFRESH_PROGRESS_VIEWS)
removeMessages(CMD_REFRESH_PROGRESS_VIEWS)
sendMessageDelayed(message, delay)
}
interface Callback {
fun onUpdateProgressViews(progress: Int, total: Int)
}
companion object {
private val CMD_REFRESH_PROGRESS_VIEWS = 1
private val MIN_INTERVAL = 20
private val UPDATE_INTERVAL_PLAYING = 1000
private val UPDATE_INTERVAL_PAUSED = 500
}
}

View file

@ -1,15 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.view.View;
public class PlayPauseButtonOnClickHandler implements View.OnClickListener {
@Override
public void onClick(View v) {
if (MusicPlayerRemote.isPlaying()) {
MusicPlayerRemote.pauseSong();
} else {
MusicPlayerRemote.resumePlaying();
}
}
}

View file

@ -0,0 +1,14 @@
package code.name.monkey.retromusic.helper
import android.view.View
class PlayPauseButtonOnClickHandler : View.OnClickListener {
override fun onClick(v: View) {
if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong()
} else {
MusicPlayerRemote.resumePlaying()
}
}
}

View file

@ -1,91 +0,0 @@
package code.name.monkey.retromusic.helper;
import android.app.SearchManager;
import android.content.Context;
import android.os.Bundle;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.model.Song;
public class SearchQueryHelper {
private static final String TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?";
private static final String ALBUM_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ALBUM + ") = ?";
private static final String ARTIST_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ARTIST + ") = ?";
private static final String AND = " AND ";
private static ArrayList<Song> songs = new ArrayList<>();
public static ArrayList<Song> getSongs() {
return songs;
}
public static void setSongs(ArrayList<Song> songs) {
SearchQueryHelper.songs = songs;
}
@NonNull
public static ArrayList<Song> getSongs(@NonNull final Context context, @NonNull final Bundle extras) {
final String query = extras.getString(SearchManager.QUERY, null);
final String artistName = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST, null);
final String albumName = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM, null);
final String titleName = extras.getString(MediaStore.EXTRA_MEDIA_TITLE, null);
ArrayList<Song> songs = new ArrayList<>();
if (artistName != null && albumName != null && titleName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION + AND + ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
if (artistName != null && titleName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION + AND + TITLE_SELECTION, new String[]{artistName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
if (albumName != null && titleName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION + AND + TITLE_SELECTION, new String[]{albumName.toLowerCase(), titleName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
if (artistName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION, new String[]{artistName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
if (albumName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION, new String[]{albumName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
if (titleName != null) {
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, TITLE_SELECTION, new String[]{titleName.toLowerCase()})).blockingFirst();
}
if (!songs.isEmpty()) {
return songs;
}
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ARTIST_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) {
return songs;
}
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, ALBUM_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) {
return songs;
}
songs = SongLoader.Companion.getSongs(SongLoader.Companion.makeSongCursor(context, TITLE_SELECTION, new String[]{query.toLowerCase()})).blockingFirst();
if (!songs.isEmpty()) {
return songs;
}
return new ArrayList<Song>();
}
}

View file

@ -0,0 +1,78 @@
package code.name.monkey.retromusic.helper
import android.app.SearchManager
import android.content.Context
import android.os.Bundle
import android.provider.MediaStore
import code.name.monkey.retromusic.loaders.SongLoader
import code.name.monkey.retromusic.model.Song
import java.util.*
object SearchQueryHelper {
private val TITLE_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.TITLE + ") = ?"
private val ALBUM_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ALBUM + ") = ?"
private val ARTIST_SELECTION = "lower(" + MediaStore.Audio.AudioColumns.ARTIST + ") = ?"
private val AND = " AND "
var songs = ArrayList<Song>()
fun getSongs(context: Context, extras: Bundle): ArrayList<Song> {
val query = extras.getString(SearchManager.QUERY, null)
val artistName = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST, null)
val albumName = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM, null)
val titleName = extras.getString(MediaStore.EXTRA_MEDIA_TITLE, null)
var songs = ArrayList<Song>()
if (artistName != null && albumName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION + AND + ALBUM_SELECTION + AND + TITLE_SELECTION, arrayOf(artistName.toLowerCase(), albumName.toLowerCase(), titleName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
if (artistName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION + AND + TITLE_SELECTION, arrayOf(artistName.toLowerCase(), titleName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
if (albumName != null && titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION + AND + TITLE_SELECTION, arrayOf(albumName.toLowerCase(), titleName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
if (artistName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION, arrayOf(artistName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
if (albumName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION, arrayOf(albumName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
if (titleName != null) {
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, TITLE_SELECTION, arrayOf(titleName.toLowerCase()))).blockingFirst()
}
if (!songs.isEmpty()) {
return songs
}
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ARTIST_SELECTION, arrayOf(query.toLowerCase()))).blockingFirst()
if (!songs.isEmpty()) {
return songs
}
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, ALBUM_SELECTION, arrayOf(query.toLowerCase()))).blockingFirst()
if (!songs.isEmpty()) {
return songs
}
songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, TITLE_SELECTION, arrayOf(query.toLowerCase()))).blockingFirst()
return if (!songs.isEmpty()) {
songs
} else ArrayList()
}
}

View file

@ -1,25 +0,0 @@
package code.name.monkey.retromusic.helper;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.model.Song;
import java.util.Collections;
import java.util.List;
public class ShuffleHelper {
public static void makeShuffleList(@NonNull List<Song> listToShuffle, final int current) {
if (listToShuffle.isEmpty()) return;
if (current >= 0) {
Song song = listToShuffle.remove(current);
Collections.shuffle(listToShuffle);
listToShuffle.add(0, song);
} else {
Collections.shuffle(listToShuffle);
}
}
}

View file

@ -0,0 +1,20 @@
package code.name.monkey.retromusic.helper
import code.name.monkey.retromusic.model.Song
import java.util.Collections
object ShuffleHelper {
fun makeShuffleList(listToShuffle: MutableList<Song>, current: Int) {
if (listToShuffle.isEmpty()) return
if (current >= 0) {
val song = listToShuffle.removeAt(current)
listToShuffle.shuffle()
listToShuffle.add(0, song)
} else {
listToShuffle.shuffle()
}
}
}

View file

@ -1,173 +0,0 @@
/*
* Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package code.name.monkey.retromusic.helper;
import android.provider.MediaStore;
/**
* Holds all of the sort orders for each list type.
*
* @author Andrew Neal (andrewdneal@gmail.com)
*/
public final class SortOrder {
/**
* This class is never instantiated
*/
public SortOrder() {
}
/**
* Artist sort order entries.
*/
public interface ArtistSortOrder {
/* Artist sort order A-Z */
String ARTIST_A_Z = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER;
/* Artist sort order Z-A */
String ARTIST_Z_A = ARTIST_A_Z + " DESC";
/* Artist sort order number of songs */
String ARTIST_NUMBER_OF_SONGS = MediaStore.Audio.Artists.NUMBER_OF_TRACKS
+ " DESC";
/* Artist sort order number of albums */
String ARTIST_NUMBER_OF_ALBUMS = MediaStore.Audio.Artists.NUMBER_OF_ALBUMS
+ " DESC";
}
/**
* Album sort order entries.
*/
public interface AlbumSortOrder {
/* Album sort order A-Z */
String ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER;
/* Album sort order Z-A */
String ALBUM_Z_A = ALBUM_A_Z + " DESC";
/* Album sort order songs */
String ALBUM_NUMBER_OF_SONGS = MediaStore.Audio.Albums.NUMBER_OF_SONGS
+ " DESC";
/* Album sort order artist */
String ALBUM_ARTIST = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER;
/* Album sort order year */
String ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC";
}
/**
* Song sort order entries.
*/
public interface SongSortOrder {
/* Song sort order A-Z */
String SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
/* Song sort order Z-A */
String SONG_Z_A = SONG_A_Z + " DESC";
/* Song sort order artist */
String SONG_ARTIST = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER;
/* Song sort order album */
String SONG_ALBUM = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER;
/* Song sort order year */
String SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC";
/* Song sort order duration */
String SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC";
/* Song sort order date */
String SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC";
}
/**
* Album song sort order entries.
*/
public interface AlbumSongSortOrder {
/* Album song sort order A-Z */
String SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
/* Album song sort order Z-A */
String SONG_Z_A = SONG_A_Z + " DESC";
/* Album song sort order track list */
String SONG_TRACK_LIST = MediaStore.Audio.Media.TRACK + ", "
+ MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
/* Album song sort order duration */
String SONG_DURATION = SongSortOrder.SONG_DURATION;
}
/**
* Artist song sort order entries.
*/
public interface ArtistSongSortOrder {
/* Artist song sort order A-Z */
String SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;
/* Artist song sort order Z-A */
String SONG_Z_A = SONG_A_Z + " DESC";
/* Artist song sort order album */
String SONG_ALBUM = MediaStore.Audio.Media.ALBUM;
/* Artist song sort order year */
String SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC";
/* Artist song sort order duration */
String SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC";
/* Artist song sort order date */
String SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC";
}
/**
* Artist album sort order entries.
*/
public interface ArtistAlbumSortOrder {
/* Artist album sort order A-Z */
String ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER;
/* Artist album sort order Z-A */
String ALBUM_Z_A = ALBUM_A_Z + " DESC";
/* Artist album sort order year */
String ALBUM_YEAR = MediaStore.Audio.Media.YEAR
+ " DESC";
/* Artist album sort order year */
String ALBUM_YEAR_ASC = MediaStore.Audio.Media.YEAR
+ " ASC";
}
/**
* Genre sort order entries.
*/
public interface GenreSortOrder {
/* Genre sort order A-Z */
String GENRE_A_Z = MediaStore.Audio.Genres.DEFAULT_SORT_ORDER;
/* Genre sort order Z-A */
String ALBUM_Z_A = GENRE_A_Z + " DESC";
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package code.name.monkey.retromusic.helper
import android.provider.MediaStore
/**
* Holds all of the sort orders for each list type.
*
* @author Andrew Neal (andrewdneal@gmail.com)
*/
/**
* This class is never instantiated
*/
class SortOrder {
/**
* Artist sort order entries.
*/
interface ArtistSortOrder {
companion object {
/* Artist sort order A-Z */
val ARTIST_A_Z = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
/* Artist sort order Z-A */
val ARTIST_Z_A = "$ARTIST_A_Z DESC"
/* Artist sort order number of songs */
val ARTIST_NUMBER_OF_SONGS = MediaStore.Audio.Artists.NUMBER_OF_TRACKS + " DESC"
/* Artist sort order number of albums */
val ARTIST_NUMBER_OF_ALBUMS = MediaStore.Audio.Artists.NUMBER_OF_ALBUMS + " DESC"
}
}
/**
* Album sort order entries.
*/
interface AlbumSortOrder {
companion object {
/* Album sort order A-Z */
val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Album sort order Z-A */
val ALBUM_Z_A = "$ALBUM_A_Z DESC"
/* Album sort order songs */
val ALBUM_NUMBER_OF_SONGS = MediaStore.Audio.Albums.NUMBER_OF_SONGS + " DESC"
/* Album sort order artist */
val ALBUM_ARTIST = (MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
+ ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER)
/* Album sort order year */
val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
}
}
/**
* Song sort order entries.
*/
interface SongSortOrder {
companion object {
/* Song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC"
/* Song sort order artist */
val SONG_ARTIST = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER
/* Song sort order album */
val SONG_ALBUM = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Song sort order year */
val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Song sort order duration */
val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC"
/* Song sort order date */
val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC"
}
}
/**
* Album song sort order entries.
*/
interface AlbumSongSortOrder {
companion object {
/* Album song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Album song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC"
/* Album song sort order track list */
val SONG_TRACK_LIST = (MediaStore.Audio.Media.TRACK + ", "
+ MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
/* Album song sort order duration */
val SONG_DURATION = SongSortOrder.SONG_DURATION
}
}
/**
* Artist song sort order entries.
*/
interface ArtistSongSortOrder {
companion object {
/* Artist song sort order A-Z */
val SONG_A_Z = MediaStore.Audio.Media.DEFAULT_SORT_ORDER
/* Artist song sort order Z-A */
val SONG_Z_A = "$SONG_A_Z DESC"
/* Artist song sort order album */
val SONG_ALBUM = MediaStore.Audio.Media.ALBUM
/* Artist song sort order year */
val SONG_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Artist song sort order duration */
val SONG_DURATION = MediaStore.Audio.Media.DURATION + " DESC"
/* Artist song sort order date */
val SONG_DATE = MediaStore.Audio.Media.DATE_ADDED + " DESC"
}
}
/**
* Artist album sort order entries.
*/
interface ArtistAlbumSortOrder {
companion object {
/* Artist album sort order A-Z */
val ALBUM_A_Z = MediaStore.Audio.Albums.DEFAULT_SORT_ORDER
/* Artist album sort order Z-A */
val ALBUM_Z_A = "$ALBUM_A_Z DESC"
/* Artist album sort order year */
val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC"
/* Artist album sort order year */
val ALBUM_YEAR_ASC = MediaStore.Audio.Media.YEAR + " ASC"
}
}
/**
* Genre sort order entries.
*/
interface GenreSortOrder {
companion object {
/* Genre sort order A-Z */
val GENRE_A_Z = MediaStore.Audio.Genres.DEFAULT_SORT_ORDER
/* Genre sort order Z-A */
val ALBUM_Z_A = "$GENRE_A_Z DESC"
}
}
}

View file

@ -1,82 +0,0 @@
package code.name.monkey.retromusic.helper;
/**
* Simple thread safe stop watch.
*
* @author Karim Abou Zeid (kabouzeid)
*/
public class StopWatch {
/**
* The time the stop watch was last started.
*/
private long startTime;
/**
* The time elapsed before the current {@link #startTime}.
*/
private long previousElapsedTime;
/**
* Whether the stop watch is currently running or not.
*/
private boolean isRunning;
/**
* Starts or continues the stop watch.
*
* @see #pause()
* @see #reset()
*/
public void start() {
synchronized (this) {
startTime = System.currentTimeMillis();
isRunning = true;
}
}
/**
* Pauses the stop watch. It can be continued later from {@link #start()}.
*
* @see #start()
* @see #reset()
*/
public void pause() {
synchronized (this) {
previousElapsedTime += System.currentTimeMillis() - startTime;
isRunning = false;
}
}
/**
* Stops and resets the stop watch to zero milliseconds.
*
* @see #start()
* @see #pause()
*/
public void reset() {
synchronized (this) {
startTime = 0;
previousElapsedTime = 0;
isRunning = false;
}
}
/**
* @return the total elapsed time in milliseconds
*/
public final long getElapsedTime() {
synchronized (this) {
long currentElapsedTime = 0;
if (isRunning) {
currentElapsedTime = System.currentTimeMillis() - startTime;
}
return previousElapsedTime + currentElapsedTime;
}
}
@Override
public String toString() {
return String.format("%d millis", getElapsedTime());
}
}

View file

@ -0,0 +1,80 @@
package code.name.monkey.retromusic.helper
/**
* Simple thread safe stop watch.
*
* @author Karim Abou Zeid (kabouzeid)
*/
class StopWatch {
/**
* The time the stop watch was last started.
*/
private var startTime: Long = 0
/**
* The time elapsed before the current [.startTime].
*/
private var previousElapsedTime: Long = 0
/**
* Whether the stop watch is currently running or not.
*/
private var isRunning: Boolean = false
/**
* @return the total elapsed time in milliseconds
*/
val elapsedTime: Long
get() = synchronized(this) {
var currentElapsedTime: Long = 0
if (isRunning) {
currentElapsedTime = System.currentTimeMillis() - startTime
}
return previousElapsedTime + currentElapsedTime
}
/**
* Starts or continues the stop watch.
*
* @see .pause
* @see .reset
*/
fun start() {
synchronized(this) {
startTime = System.currentTimeMillis()
isRunning = true
}
}
/**
* Pauses the stop watch. It can be continued later from [.start].
*
* @see .start
* @see .reset
*/
fun pause() {
synchronized(this) {
previousElapsedTime += System.currentTimeMillis() - startTime
isRunning = false
}
}
/**
* Stops and resets the stop watch to zero milliseconds.
*
* @see .start
* @see .pause
*/
fun reset() {
synchronized(this) {
startTime = 0
previousElapsedTime = 0
isRunning = false
}
}
override fun toString(): String {
return String.format("%d millis", elapsedTime)
}
}

View file

@ -1,50 +0,0 @@
package code.name.monkey.retromusic.helper.menu;
import android.app.Activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.view.MenuItem;
import java.util.ArrayList;
import code.name.monkey.retromusic.loaders.GenreLoader;
import code.name.monkey.retromusic.model.Genre;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
/**
* @author Hemanth S (h4h13).
*/
public class GenreMenuHelper {
public static boolean handleMenuClick(@NonNull AppCompatActivity activity,
@NonNull Genre genre,
@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_play:
MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true);
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(getGenreSongs(activity, genre));
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialog.create(getGenreSongs(activity, genre))
.show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(getGenreSongs(activity, genre));
return true;
}
return false;
}
@NonNull
private static ArrayList<Song> getGenreSongs(@NonNull Activity activity,
@NonNull Genre genre) {
ArrayList<Song> songs;
songs = GenreLoader.getSongs(activity, genre.id).blockingFirst();
return songs;
}
}

View file

@ -0,0 +1,52 @@
package code.name.monkey.retromusic.helper.menu
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import java.util.ArrayList
import code.name.monkey.retromusic.loaders.GenreLoader
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
/**
* @author Hemanth S (h4h13).
*/
object GenreMenuHelper {
fun handleMenuClick(activity: AppCompatActivity,
genre: Genre,
item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_play -> {
MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true)
return true
}
R.id.action_play_next -> {
MusicPlayerRemote.playNext(getGenreSongs(activity, genre))
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(getGenreSongs(activity, genre))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(getGenreSongs(activity, genre))
return true
}
}
return false
}
private fun getGenreSongs(activity: Activity,
genre: Genre): ArrayList<Song> {
val songs: ArrayList<Song>
songs = GenreLoader.getSongs(activity, genre.id).blockingFirst()
return songs
}
}

View file

@ -1,91 +0,0 @@
package code.name.monkey.retromusic.helper.menu;
import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.ArrayList;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog;
import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
import code.name.monkey.retromusic.misc.WeakContextAsyncTask;
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.PlaylistsUtil;
public class PlaylistMenuHelper {
public static boolean handleMenuClick(@NonNull AppCompatActivity activity,
@NonNull final Playlist playlist, @NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_play:
MusicPlayerRemote.openQueue(getPlaylistSongs(activity, playlist), 9, true);
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(getPlaylistSongs(activity, playlist));
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialog.create(getPlaylistSongs(activity, playlist))
.show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(getPlaylistSongs(activity, playlist));
return true;
case R.id.action_rename_playlist:
RenamePlaylistDialog.create(playlist.id)
.show(activity.getSupportFragmentManager(), "RENAME_PLAYLIST");
return true;
case R.id.action_delete_playlist:
DeletePlaylistDialog.create(playlist)
.show(activity.getSupportFragmentManager(), "DELETE_PLAYLIST");
return true;
case R.id.action_save_playlist:
new SavePlaylistAsyncTask(activity).execute(playlist);
return true;
}
return false;
}
@NonNull
private static ArrayList<Song> getPlaylistSongs(@NonNull Activity activity,
@NonNull Playlist playlist) {
ArrayList<Song> songs;
if (playlist instanceof AbsCustomPlaylist) {
songs = ((AbsCustomPlaylist) playlist).getSongs(activity).blockingFirst();
} else {
songs = PlaylistSongsLoader.getPlaylistSongList(activity, playlist).blockingFirst();
}
return songs;
}
private static class SavePlaylistAsyncTask extends WeakContextAsyncTask<Playlist, String, String> {
SavePlaylistAsyncTask(Context context) {
super(context);
}
@Override
protected String doInBackground(Playlist... params) {
return String.format(RetroApplication.getInstance().getApplicationContext().getString(R.string
.saved_playlist_to), PlaylistsUtil.savePlaylist(RetroApplication.getInstance().getApplicationContext(), params[0]).blockingFirst());
}
@Override
protected void onPostExecute(String string) {
super.onPostExecute(string);
Context context = getContext();
if (context != null) {
Toast.makeText(context, string, Toast.LENGTH_LONG).show();
}
}
}
}

View file

@ -0,0 +1,91 @@
package code.name.monkey.retromusic.helper.menu
import android.app.Activity
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import android.widget.Toast
import java.util.ArrayList
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroApplication
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.misc.WeakContextAsyncTask
import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PlaylistsUtil
object PlaylistMenuHelper {
fun handleMenuClick(activity: AppCompatActivity,
playlist: Playlist, item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_play -> {
MusicPlayerRemote.openQueue(getPlaylistSongs(activity, playlist), 9, true)
return true
}
R.id.action_play_next -> {
MusicPlayerRemote.playNext(getPlaylistSongs(activity, playlist))
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(getPlaylistSongs(activity, playlist))
.show(activity.supportFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(getPlaylistSongs(activity, playlist))
return true
}
R.id.action_rename_playlist -> {
RenamePlaylistDialog.create(playlist.id.toLong())
.show(activity.supportFragmentManager, "RENAME_PLAYLIST")
return true
}
R.id.action_delete_playlist -> {
DeletePlaylistDialog.create(playlist)
.show(activity.supportFragmentManager, "DELETE_PLAYLIST")
return true
}
R.id.action_save_playlist -> {
SavePlaylistAsyncTask(activity).execute(playlist)
return true
}
}
return false
}
private fun getPlaylistSongs(activity: Activity,
playlist: Playlist): ArrayList<Song> {
val songs: ArrayList<Song>
if (playlist is AbsCustomPlaylist) {
songs = playlist.getSongs(activity).blockingFirst()
} else {
songs = PlaylistSongsLoader.getPlaylistSongList(activity, playlist).blockingFirst()
}
return songs
}
private class SavePlaylistAsyncTask internal constructor(context: Context) : WeakContextAsyncTask<Playlist, String, String>(context) {
override fun doInBackground(vararg params: Playlist): String {
return String.format(RetroApplication.instance.applicationContext.getString(R.string
.saved_playlist_to), PlaylistsUtil.savePlaylist(RetroApplication.instance.applicationContext, params[0]).blockingFirst())
}
override fun onPostExecute(string: String) {
super.onPostExecute(string)
val context = context
if (context != null) {
Toast.makeText(context, string, Toast.LENGTH_LONG).show()
}
}
}
}

View file

@ -1,93 +0,0 @@
package code.name.monkey.retromusic.helper.menu;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog;
import code.name.monkey.retromusic.dialogs.SongDetailDialog;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
import code.name.monkey.retromusic.interfaces.PaletteColorHolder;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity;
import code.name.monkey.retromusic.ui.activities.tageditor.SongTagEditorActivity;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.NavigationUtil;
public class SongMenuHelper {
public static final int MENU_RES = R.menu.menu_item_song;
public static boolean handleMenuClick(@NonNull FragmentActivity activity, @NonNull Song song, int menuItemId) {
switch (menuItemId) {
case R.id.action_set_as_ringtone:
MusicUtil.setRingtone(activity, song.id);
return true;
case R.id.action_share:
activity.startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(song, activity), null));
return true;
case R.id.action_delete_from_device:
DeleteSongsDialog.create(song).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialog.create(song).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
return true;
case R.id.action_play_next:
MusicPlayerRemote.playNext(song);
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(song);
return true;
case R.id.action_tag_editor:
Intent tagEditorIntent = new Intent(activity, SongTagEditorActivity.class);
tagEditorIntent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
if (activity instanceof PaletteColorHolder)
tagEditorIntent.putExtra(AbsTagEditorActivity.EXTRA_PALETTE, ((PaletteColorHolder) activity).getPaletteColor());
activity.startActivity(tagEditorIntent);
return true;
case R.id.action_details:
SongDetailDialog.create(song).show(activity.getSupportFragmentManager(), "SONG_DETAILS");
return true;
case R.id.action_go_to_album:
NavigationUtil.goToAlbum(activity, song.albumId);
return true;
case R.id.action_go_to_artist:
NavigationUtil.goToArtist(activity, song.artistId);
return true;
}
return false;
}
public static abstract class OnClickSongMenu implements View.OnClickListener, PopupMenu.OnMenuItemClickListener {
private AppCompatActivity activity;
protected OnClickSongMenu(@NonNull AppCompatActivity activity) {
this.activity = activity;
}
public int getMenuRes() {
return MENU_RES;
}
@Override
public void onClick(View v) {
PopupMenu popupMenu = new PopupMenu(activity, v);
popupMenu.inflate(getMenuRes());
popupMenu.setOnMenuItemClickListener(this);
popupMenu.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return handleMenuClick(activity, getSong(), item.getItemId());
}
public abstract Song getSong();
}
}

View file

@ -0,0 +1,93 @@
package code.name.monkey.retromusic.helper.menu
import android.content.Intent
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.dialogs.SongDetailDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.ui.activities.tageditor.SongTagEditorActivity
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil
object SongMenuHelper {
val MENU_RES = R.menu.menu_item_song
fun handleMenuClick(activity: FragmentActivity, song: Song, menuItemId: Int): Boolean {
when (menuItemId) {
R.id.action_set_as_ringtone -> {
MusicUtil.setRingtone(activity, song.id)
return true
}
R.id.action_share -> {
activity.startActivity(Intent.createChooser(MusicUtil.createShareSongFileIntent(song, activity), null))
return true
}
R.id.action_delete_from_device -> {
DeleteSongsDialog.create(song).show(activity.supportFragmentManager, "DELETE_SONGS")
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(song).show(activity.supportFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_play_next -> {
MusicPlayerRemote.playNext(song)
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(song)
return true
}
R.id.action_tag_editor -> {
val tagEditorIntent = Intent(activity, SongTagEditorActivity::class.java)
tagEditorIntent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id)
if (activity is PaletteColorHolder)
tagEditorIntent.putExtra(AbsTagEditorActivity.EXTRA_PALETTE, (activity as PaletteColorHolder).paletteColor)
activity.startActivity(tagEditorIntent)
return true
}
R.id.action_details -> {
SongDetailDialog.create(song).show(activity.supportFragmentManager, "SONG_DETAILS")
return true
}
R.id.action_go_to_album -> {
NavigationUtil.goToAlbum(activity, song.albumId)
return true
}
R.id.action_go_to_artist -> {
NavigationUtil.goToArtist(activity, song.artistId)
return true
}
}
return false
}
abstract class OnClickSongMenu protected constructor(private val activity: AppCompatActivity) : View.OnClickListener, PopupMenu.OnMenuItemClickListener {
open val menuRes: Int
get() = MENU_RES
abstract val song: Song
override fun onClick(v: View) {
val popupMenu = PopupMenu(activity, v)
popupMenu.inflate(menuRes)
popupMenu.setOnMenuItemClickListener(this)
popupMenu.show()
}
override fun onMenuItemClick(item: MenuItem): Boolean {
return handleMenuClick(activity, song, item.itemId)
}
}
}

View file

@ -1,35 +0,0 @@
package code.name.monkey.retromusic.helper.menu;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import code.name.monkey.retromusic.model.Song;
import java.util.ArrayList;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog;
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
public class SongsMenuHelper {
public static boolean handleMenuClick(@NonNull FragmentActivity activity, @NonNull ArrayList<Song> songs, int menuItemId) {
switch (menuItemId) {
case R.id.action_play_next:
MusicPlayerRemote.playNext(songs);
return true;
case R.id.action_add_to_current_playing:
MusicPlayerRemote.enqueue(songs);
return true;
case R.id.action_add_to_playlist:
AddToPlaylistDialog.create(songs).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
return true;
case R.id.action_delete_from_device:
DeleteSongsDialog.create(songs).show(activity.getSupportFragmentManager(), "DELETE_SONGS");
return true;
}
return false;
}
}

View file

@ -0,0 +1,34 @@
package code.name.monkey.retromusic.helper.menu
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import java.util.*
object SongsMenuHelper {
fun handleMenuClick(activity: FragmentActivity, songs: ArrayList<Song>, menuItemId: Int): Boolean {
when (menuItemId) {
R.id.action_play_next -> {
MusicPlayerRemote.playNext(songs)
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(songs)
return true
}
R.id.action_add_to_playlist -> {
AddToPlaylistDialog.create(songs).show(activity.supportFragmentManager, "ADD_PLAYLIST")
return true
}
R.id.action_delete_from_device -> {
DeleteSongsDialog.create(songs).show(activity.supportFragmentManager, "DELETE_SONGS")
return true
}
}
return false
}
}