clean up playback interface and a few other classes

This commit is contained in:
dkanada 2020-05-23 11:01:55 +09:00
commit 7edf0c85fa
12 changed files with 50 additions and 242 deletions

View file

@ -68,7 +68,6 @@ import java.util.List;
* complete}
*/
public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
public static final String TAG = CustomFragmentStatePagerAdapter.class.getSimpleName();
private static final boolean DEBUG = false;
@ -83,9 +82,6 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
mFragmentManager = fm;
}
/**
* Return the Fragment associated with a specified position.
*/
public abstract Fragment getItem(int position);
@Override
@ -117,9 +113,11 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
fragment.setInitialSavedState(fss);
}
}
while (mFragments.size() <= position) {
mFragments.add(null);
}
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
mFragments.set(position, fragment);
@ -135,11 +133,13 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment) object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
mFragments.set(position, null);
@ -158,6 +158,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
@ -185,6 +186,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
mSavedState.toArray(fss);
state.putParcelableArray("states", fss);
}
for (int i = 0; i < mFragments.size(); i++) {
Fragment f = mFragments.get(i);
if (f != null && f.isAdded()) {
@ -195,6 +197,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
mFragmentManager.putFragment(state, key, f);
}
}
return state;
}
@ -211,6 +214,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
mSavedState.add((Fragment.SavedState) fs);
}
}
Iterable<String> keys = bundle.keySet();
for (String key : keys) {
if (key.startsWith("f")) {
@ -234,6 +238,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
if (position < mFragments.size() && position >= 0) {
return mFragments.get(position);
}
return null;
}
}

View file

@ -1,89 +0,0 @@
package com.dkanada.gramophone.misc;
import android.app.Dialog;
import android.content.Context;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
public abstract class DialogAsyncTask<Params, Progress, Result> extends WeakContextAsyncTask<Params, Progress, Result> {
private final int delay;
private WeakReference<Dialog> dialogWeakReference;
private boolean supposedToBeDismissed;
public DialogAsyncTask(Context context) {
this(context, 0);
}
public DialogAsyncTask(Context context, int showDelay) {
super(context);
this.delay = showDelay;
dialogWeakReference = new WeakReference<>(null);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (delay > 0) {
new Handler().postDelayed(this::initAndShowDialog, delay);
} else {
initAndShowDialog();
}
}
private void initAndShowDialog() {
Context context = getContext();
if (!supposedToBeDismissed && context != null) {
Dialog dialog = createDialog(context);
dialogWeakReference = new WeakReference<>(dialog);
dialog.show();
}
}
@SuppressWarnings("unchecked")
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
Dialog dialog = getDialog();
if (dialog != null) {
onProgressUpdate(dialog, values);
}
}
@SuppressWarnings("unchecked")
protected void onProgressUpdate(@NonNull Dialog dialog, Progress... values) {
}
@Nullable
protected Dialog getDialog() {
return dialogWeakReference.get();
}
@Override
protected void onCancelled(Result result) {
super.onCancelled(result);
tryToDismiss();
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
tryToDismiss();
}
private void tryToDismiss() {
supposedToBeDismissed = true;
try {
Dialog dialog = getDialog();
if (dialog != null)
dialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
protected abstract Dialog createDialog(@NonNull Context context);
}

View file

@ -5,21 +5,17 @@ import android.animation.Animator;
public abstract class SimpleAnimatorListener implements Animator.AnimatorListener {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}

View file

@ -1,20 +0,0 @@
package com.dkanada.gramophone.misc;
import android.content.Context;
import android.os.AsyncTask;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
public abstract class WeakContextAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private WeakReference<Context> contextWeakReference;
public WeakContextAsyncTask(Context context) {
contextWeakReference = new WeakReference<>(context);
}
@Nullable
protected Context getContext() {
return contextWeakReference.get();
}
}

View file

@ -1,72 +0,0 @@
package com.dkanada.gramophone.misc;
import android.content.Context;
import androidx.loader.content.AsyncTaskLoader;
/**
* <a href="http://code.google.com/p/android/issues/detail?id=14944">Issue
* 14944</a>
*
* @author Alexander Blom
*/
public abstract class WrappedAsyncTaskLoader<D> extends AsyncTaskLoader<D> {
private D mData;
/**
* Constructor of <code>WrappedAsyncTaskLoader</code>
*
* @param context The {@link Context} to use.
*/
public WrappedAsyncTaskLoader(Context context) {
super(context);
}
/**
* {@inheritDoc}
*/
@Override
public void deliverResult(D data) {
if (!isReset()) {
this.mData = data;
super.deliverResult(data);
} else {
// An asynchronous query came in while the loader is stopped
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onStartLoading() {
super.onStartLoading();
if (this.mData != null) {
deliverResult(this.mData);
} else if (takeContentChanged() || this.mData == null) {
forceLoad();
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onStopLoading() {
super.onStopLoading();
// Attempt to cancel the current load task if possible
cancelLoad();
}
/**
* {@inheritDoc}
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
this.mData = null;
}
}

View file

@ -46,7 +46,6 @@ public class MultiPlayer implements Playback {
private boolean isReady = false;
private boolean isPlaying = false;
private boolean isNew = false;
private boolean isFirst = true;
private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() {
@Override
@ -118,7 +117,7 @@ public class MultiPlayer implements Playback {
}
@Override
public void setNextDataSource(@Nullable final String path) {
public void queueDataSource(@Nullable final String path) {
if (context == null) {
return;
}
@ -151,11 +150,7 @@ public class MultiPlayer implements Playback {
}
mediaSource.addMediaSource(source);
if (!isFirst && next) {
start();
}
isFirst = false;
if (next) start();
}
});
}
@ -171,7 +166,7 @@ public class MultiPlayer implements Playback {
}
@Override
public boolean start() {
public void start() {
isPlaying = true;
exoPlayer.setPlayWhenReady(true);
@ -179,8 +174,6 @@ public class MultiPlayer implements Playback {
callbacks.onTrackStarted();
isNew = false;
}
return true;
}
@Override
@ -190,10 +183,9 @@ public class MultiPlayer implements Playback {
}
@Override
public boolean pause() {
public void pause() {
isPlaying = false;
exoPlayer.setPlayWhenReady(false);
return true;
}
@Override
@ -220,8 +212,7 @@ public class MultiPlayer implements Playback {
}
@Override
public boolean setVolume(float volume) {
public void setVolume(float volume) {
exoPlayer.setVolume(volume);
return true;
}
}

View file

@ -218,6 +218,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
if (audioManager == null) {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
return audioManager;
}
@ -422,7 +423,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
this.playingQueue = restoredQueue;
position = restoredPosition;
openCurrent();
openCurrent(true);
if (restoredPositionInTrack > 0) seek(restoredPositionInTrack);
@ -471,18 +472,25 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
synchronized (this) {
this.position = position;
openCurrent();
openCurrent(false);
notifyChange(META_CHANGED);
notHandledMetaChangedForCurrentTrack = false;
}
}
private void openCurrent() {
private void openCurrent(boolean queue) {
synchronized (this) {
// current song will be null when queue is cleared
if (getCurrentSong() == null) return;
playback.setDataSource(getTrackUri(getCurrentSong()));
if (queue) {
// restore queue from database
playback.queueDataSource(getTrackUri(getCurrentSong()));
} else {
// set current song and start playback
playback.setDataSource(getTrackUri(getCurrentSong()));
}
}
}
@ -494,7 +502,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void prepareNextImpl() {
synchronized (this) {
nextPosition = getNextPosition(false);
playback.setNextDataSource(getTrackUri(getSongAt(nextPosition)));
playback.queueDataSource(getTrackUri(getSongAt(nextPosition)));
}
}

View file

@ -1,31 +1,29 @@
package com.dkanada.gramophone.service.playback;
import androidx.annotation.Nullable;
public interface Playback {
void setDataSource(String path);
void setNextDataSource(@Nullable String path);
void queueDataSource(String path);
void setCallbacks(PlaybackCallbacks callbacks);
boolean isInitialized();
void start();
boolean start();
void pause();
void stop();
boolean pause();
boolean isInitialized();
boolean isPlaying();
int duration();
int position();
int seek(int whereto);
int duration();
boolean setVolume(float vol);
int seek(int position);
void setVolume(float volume);
interface PlaybackCallbacks {
void onTrackStarted();

View file

@ -18,9 +18,6 @@ import android.view.View;
import com.kabouzeid.appthemehelper.ThemeStore;
import com.dkanada.gramophone.R;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public abstract class AbsBaseActivity extends AbsThemeActivity {
public static final int PERMISSION_REQUEST = 100;
@ -69,11 +66,11 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
showOverflowMenu();
return true;
}
return super.dispatchKeyEvent(event);
}
protected void showOverflowMenu() {
}
@Nullable
@ -107,6 +104,7 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
}
}
}
return true;
}
@ -117,14 +115,14 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(AbsBaseActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//User has deny from permission dialog
// user has deny from permission dialog
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.action_grant, view -> requestPermissions())
.setActionTextColor(ThemeStore.accentColor(this))
.show();
} else {
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
// user has deny permission and checked never show permission dialog so you can redirect to application settings page
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.action_settings, view -> {
@ -140,6 +138,7 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
return;
}
}
hadPermissions = true;
onHasPermissionsChanged(true);
}

View file

@ -21,9 +21,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements MusicServiceEventListener {
private final List<MusicServiceEventListener> mMusicServiceEventListeners = new ArrayList<>();
@ -206,7 +203,9 @@ public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements
protected void onHasPermissionsChanged(boolean hasPermissions) {
super.onHasPermissionsChanged(hasPermissions);
Intent intent = new Intent(MusicService.MEDIA_STORE_CHANGED);
intent.putExtra("from_permissions_changed", true); // just in case we need to know this at some point
// just in case we need to know this at some point
intent.putExtra("from_permissions_changed", true);
sendBroadcast(intent);
}

View file

@ -28,12 +28,6 @@ import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* @author Karim Abou Zeid (kabouzeid)
* <p/>
* Do not use {@link #setContentView(int)}. Instead wrap your layout with
* {@link #wrapSlidingMusicPanel(int)} first and then return it in {@link #createContentView()}
*/
public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivity implements SlidingUpPanelLayout.PanelSlideListener, CardPlayerFragment.Callbacks {
@BindView(R.id.sliding_layout)
@ -57,7 +51,9 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
ButterKnife.bind(this);
currentNowPlayingScreen = PreferenceUtil.getInstance(this).getNowPlayingScreen();
Fragment fragment; // must implement AbsPlayerFragment
// must implement AbsPlayerFragment
Fragment fragment;
switch (currentNowPlayingScreen) {
case FLAT:
fragment = new FlatPlayerFragment();

View file

@ -15,10 +15,6 @@ import com.dkanada.gramophone.R;
import com.dkanada.gramophone.util.PreferenceUtil;
import com.dkanada.gramophone.util.Util;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public abstract class AbsThemeActivity extends ATHToolbarActivity {
@Override
@ -29,10 +25,11 @@ public abstract class AbsThemeActivity extends ATHToolbarActivity {
}
protected void setDrawUnderStatusbar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Util.setAllowDrawUnderStatusBar(getWindow());
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Util.setStatusBarTranslucent(getWindow());
}
}
/**
@ -59,7 +56,7 @@ public abstract class AbsThemeActivity extends ATHToolbarActivity {
}
public void setStatusbarColorAuto() {
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
// we don't want to use status bar color because we are darkening the color on our own to support KitKat
setStatusbarColor(ThemeStore.primaryColor(this));
}