clean up playback interface and a few other classes
This commit is contained in:
parent
cf03b05809
commit
7edf0c85fa
12 changed files with 50 additions and 242 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue