Fix repeat and shuffle mode not displayed correctly on device restart.
This commit is contained in:
parent
431cf23da3
commit
e0cb18da1a
2 changed files with 68 additions and 69 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -36,6 +36,7 @@ local.properties
|
||||||
*.iml
|
*.iml
|
||||||
.idea
|
.idea
|
||||||
ajcore.*.txt
|
ajcore.*.txt
|
||||||
|
captures/
|
||||||
|
|
||||||
# Mac
|
# Mac
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -86,22 +86,19 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
public static final String SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK";
|
public static final String SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK";
|
||||||
public static final String SAVED_SHUFFLE_MODE = "SHUFFLE_MODE";
|
public static final String SAVED_SHUFFLE_MODE = "SHUFFLE_MODE";
|
||||||
public static final String SAVED_REPEAT_MODE = "REPEAT_MODE";
|
public static final String SAVED_REPEAT_MODE = "REPEAT_MODE";
|
||||||
|
|
||||||
private static final int FOCUS_CHANGE = 5;
|
|
||||||
private static final int DUCK = 6;
|
|
||||||
private static final int UNDUCK = 7;
|
|
||||||
public static final int RELEASE_WAKELOCK = 10;
|
public static final int RELEASE_WAKELOCK = 10;
|
||||||
public static final int TRACK_ENDED = 11;
|
public static final int TRACK_ENDED = 11;
|
||||||
public static final int TRACK_WENT_TO_NEXT = 12;
|
public static final int TRACK_WENT_TO_NEXT = 12;
|
||||||
public static final int PLAY_SONG = 13;
|
public static final int PLAY_SONG = 13;
|
||||||
public static final int SAVE_QUEUES = 14;
|
public static final int SAVE_QUEUES = 14;
|
||||||
|
|
||||||
public static final int SHUFFLE_MODE_NONE = 0;
|
public static final int SHUFFLE_MODE_NONE = 0;
|
||||||
public static final int SHUFFLE_MODE_SHUFFLE = 1;
|
public static final int SHUFFLE_MODE_SHUFFLE = 1;
|
||||||
public static final int REPEAT_MODE_NONE = 0;
|
public static final int REPEAT_MODE_NONE = 0;
|
||||||
public static final int REPEAT_MODE_ALL = 1;
|
public static final int REPEAT_MODE_ALL = 1;
|
||||||
public static final int REPEAT_MODE_THIS = 2;
|
public static final int REPEAT_MODE_THIS = 2;
|
||||||
|
private static final int FOCUS_CHANGE = 5;
|
||||||
|
private static final int DUCK = 6;
|
||||||
|
private static final int UNDUCK = 7;
|
||||||
private final IBinder musicBind = new MusicBinder();
|
private final IBinder musicBind = new MusicBinder();
|
||||||
|
|
||||||
private MultiPlayer player;
|
private MultiPlayer player;
|
||||||
|
|
@ -118,15 +115,33 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
private RemoteControlClient remoteControlClient;
|
private RemoteControlClient remoteControlClient;
|
||||||
private PowerManager.WakeLock wakeLock;
|
private PowerManager.WakeLock wakeLock;
|
||||||
private MusicPlayerHandler playerHandler;
|
private MusicPlayerHandler playerHandler;
|
||||||
|
private final AudioManager.OnAudioFocusChangeListener audioFocusListener = new AudioManager.OnAudioFocusChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onAudioFocusChange(final int focusChange) {
|
||||||
|
playerHandler.obtainMessage(FOCUS_CHANGE, focusChange, 0).sendToTarget();
|
||||||
|
}
|
||||||
|
};
|
||||||
private QueueSaveHandler queueSaveHandler;
|
private QueueSaveHandler queueSaveHandler;
|
||||||
private HandlerThread musicPlayerHandlerThread;
|
private HandlerThread musicPlayerHandlerThread;
|
||||||
private HandlerThread queueSaveHandlerThread;
|
private HandlerThread queueSaveHandlerThread;
|
||||||
private RecentlyPlayedStore recentlyPlayedStore;
|
private RecentlyPlayedStore recentlyPlayedStore;
|
||||||
private SongPlayCountStore songPlayCountStore;
|
private SongPlayCountStore songPlayCountStore;
|
||||||
|
private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, @NonNull Intent intent) {
|
||||||
|
if (intent.getAction().equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
private ContentObserver mediaStoreObserver;
|
private ContentObserver mediaStoreObserver;
|
||||||
private boolean notNotifiedMetaChangedForCurrentTrack;
|
private boolean notHandledMetaChangedForCurrentTrack;
|
||||||
private boolean isServiceInUse;
|
private boolean isServiceInUse;
|
||||||
|
|
||||||
|
private static String getTrackUri(@NonNull Song song) {
|
||||||
|
return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id).toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
@ -150,15 +165,15 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
musicPlayerHandlerThread.start();
|
musicPlayerHandlerThread.start();
|
||||||
playerHandler = new MusicPlayerHandler(this, musicPlayerHandlerThread.getLooper());
|
playerHandler = new MusicPlayerHandler(this, musicPlayerHandlerThread.getLooper());
|
||||||
|
|
||||||
|
player = new MultiPlayer(this);
|
||||||
|
player.setHandler(playerHandler);
|
||||||
|
|
||||||
// queue saving needs to run on a separate thread so that it doesn't block the player handler events
|
// queue saving needs to run on a separate thread so that it doesn't block the player handler events
|
||||||
queueSaveHandlerThread = new HandlerThread("QueueSaveHandler",
|
queueSaveHandlerThread = new HandlerThread("QueueSaveHandler",
|
||||||
Process.THREAD_PRIORITY_BACKGROUND);
|
Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
queueSaveHandlerThread.start();
|
queueSaveHandlerThread.start();
|
||||||
queueSaveHandler = new QueueSaveHandler(this, queueSaveHandlerThread.getLooper());
|
queueSaveHandler = new QueueSaveHandler(this, queueSaveHandlerThread.getLooper());
|
||||||
|
|
||||||
player = new MultiPlayer(this);
|
|
||||||
player.setHandler(playerHandler);
|
|
||||||
|
|
||||||
registerReceiversAndRemoteControlClient();
|
registerReceiversAndRemoteControlClient();
|
||||||
|
|
||||||
restoreQueueAndPosition();
|
restoreQueueAndPosition();
|
||||||
|
|
@ -170,24 +185,11 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mediaStoreObserver);
|
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mediaStoreObserver);
|
||||||
|
|
||||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
||||||
|
|
||||||
|
notifyChange(SHUFFLE_MODE_CHANGED);
|
||||||
|
notifyChange(REPEAT_MODE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, @NonNull Intent intent) {
|
|
||||||
if (intent.getAction().equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
|
|
||||||
pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final AudioManager.OnAudioFocusChangeListener audioFocusListener = new AudioManager.OnAudioFocusChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onAudioFocusChange(final int focusChange) {
|
|
||||||
playerHandler.obtainMessage(FOCUS_CHANGE, focusChange, 0).sendToTarget();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void registerReceiversAndRemoteControlClient() {
|
private void registerReceiversAndRemoteControlClient() {
|
||||||
if (!receiversAndRemoteControlClientRegistered) {
|
if (!receiversAndRemoteControlClientRegistered) {
|
||||||
registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
|
registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
|
||||||
|
|
@ -379,7 +381,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
boolean prepared = openCurrent();
|
boolean prepared = openCurrent();
|
||||||
if (prepared) prepareNext();
|
if (prepared) prepareNext();
|
||||||
notifyChange(META_CHANGED);
|
notifyChange(META_CHANGED);
|
||||||
notNotifiedMetaChangedForCurrentTrack = false;
|
notHandledMetaChangedForCurrentTrack = false;
|
||||||
return prepared;
|
return prepared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -498,10 +500,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
WidgetMedium.updateWidgets(this, getCurrentSong(), isPlaying());
|
WidgetMedium.updateWidgets(this, getCurrentSong(), isPlaying());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getTrackUri(@NonNull Song song) {
|
|
||||||
return ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNextPosition(boolean force) {
|
public int getNextPosition(boolean force) {
|
||||||
int position = getPosition() + 1;
|
int position = getPosition() + 1;
|
||||||
switch (getRepeatMode()) {
|
switch (getRepeatMode()) {
|
||||||
|
|
@ -589,7 +587,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
|
|
||||||
if (restoredPositionInTrack > 0) seek(restoredPositionInTrack);
|
if (restoredPositionInTrack > 0) seek(restoredPositionInTrack);
|
||||||
|
|
||||||
notNotifiedMetaChangedForCurrentTrack = true;
|
notHandledMetaChangedForCurrentTrack = true;
|
||||||
sendChangeIntent(META_CHANGED);
|
sendChangeIntent(META_CHANGED);
|
||||||
updateWidgets();
|
updateWidgets();
|
||||||
}
|
}
|
||||||
|
|
@ -683,9 +681,9 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
} else {
|
} else {
|
||||||
registerReceiversAndRemoteControlClient();
|
registerReceiversAndRemoteControlClient();
|
||||||
player.start();
|
player.start();
|
||||||
if (notNotifiedMetaChangedForCurrentTrack) {
|
if (notHandledMetaChangedForCurrentTrack) {
|
||||||
notifyChange(META_CHANGED);
|
handleChange(META_CHANGED);
|
||||||
notNotifiedMetaChangedForCurrentTrack = false;
|
notHandledMetaChangedForCurrentTrack = false;
|
||||||
}
|
}
|
||||||
notifyChange(PLAY_STATE_CHANGED);
|
notifyChange(PLAY_STATE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
@ -885,13 +883,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MusicBinder extends Binder {
|
|
||||||
@NonNull
|
|
||||||
public MusicService getService() {
|
|
||||||
return MusicService.this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class QueueSaveHandler extends Handler {
|
private static final class QueueSaveHandler extends Handler {
|
||||||
@NonNull
|
@NonNull
|
||||||
private final WeakReference<MusicService> mService;
|
private final WeakReference<MusicService> mService;
|
||||||
|
|
@ -912,33 +903,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MediaStoreObserver extends ContentObserver implements Runnable {
|
|
||||||
// milliseconds to delay before calling refresh to aggregate events
|
|
||||||
private static final long REFRESH_DELAY = 500;
|
|
||||||
private Handler mHandler;
|
|
||||||
|
|
||||||
public MediaStoreObserver(Handler handler) {
|
|
||||||
super(handler);
|
|
||||||
mHandler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange) {
|
|
||||||
// if a change is detected, remove any scheduled callback
|
|
||||||
// then post a new one. This is intended to prevent closely
|
|
||||||
// spaced events from generating multiple refresh calls
|
|
||||||
mHandler.removeCallbacks(this);
|
|
||||||
mHandler.postDelayed(this, REFRESH_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// actually call refresh when the delayed callback fires
|
|
||||||
// do not send a sticky broadcast here
|
|
||||||
sendBroadcast(new Intent(MEDIA_STORE_CHANGED));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class MusicPlayerHandler extends Handler {
|
private static final class MusicPlayerHandler extends Handler {
|
||||||
@NonNull
|
@NonNull
|
||||||
private final WeakReference<MusicService> mService;
|
private final WeakReference<MusicService> mService;
|
||||||
|
|
@ -1043,4 +1007,38 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MusicBinder extends Binder {
|
||||||
|
@NonNull
|
||||||
|
public MusicService getService() {
|
||||||
|
return MusicService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MediaStoreObserver extends ContentObserver implements Runnable {
|
||||||
|
// milliseconds to delay before calling refresh to aggregate events
|
||||||
|
private static final long REFRESH_DELAY = 500;
|
||||||
|
private Handler mHandler;
|
||||||
|
|
||||||
|
public MediaStoreObserver(Handler handler) {
|
||||||
|
super(handler);
|
||||||
|
mHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
// if a change is detected, remove any scheduled callback
|
||||||
|
// then post a new one. This is intended to prevent closely
|
||||||
|
// spaced events from generating multiple refresh calls
|
||||||
|
mHandler.removeCallbacks(this);
|
||||||
|
mHandler.postDelayed(this, REFRESH_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// actually call refresh when the delayed callback fires
|
||||||
|
// do not send a sticky broadcast here
|
||||||
|
sendBroadcast(new Intent(MEDIA_STORE_CHANGED));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue