seekbar crash fix
This commit is contained in:
parent
9e4cb9b885
commit
1575aab04d
|
|
@ -26,9 +26,17 @@ import android.os.Handler;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.widget.ImageView;
|
import android.view.View;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
|
import org.roboswag.core.log.Lc;
|
||||||
|
import org.roboswag.core.utils.ShouldNotHappenException;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
import rx.Subscription;
|
import rx.Subscription;
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
|
@ -58,14 +66,8 @@ public final class VolumeController {
|
||||||
private final BehaviorSubject<Integer> volumeSubject;
|
private final BehaviorSubject<Integer> volumeSubject;
|
||||||
private final Observable<Integer> volumeObservable;
|
private final Observable<Integer> volumeObservable;
|
||||||
|
|
||||||
@Nullable
|
private final Map<SeekBar, Subscription> seekBars = new HashMap<>();
|
||||||
private SeekBar seekBar;
|
private final Set<VolumeButtons> volumeButtonsSet = new HashSet<>();
|
||||||
@Nullable
|
|
||||||
private ImageView volumeDown;
|
|
||||||
@Nullable
|
|
||||||
private ImageView volumeUp;
|
|
||||||
@Nullable
|
|
||||||
private Subscription seekBarSubscription;
|
|
||||||
|
|
||||||
private VolumeController(@NonNull final Context context) {
|
private VolumeController(@NonNull final Context context) {
|
||||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
|
|
@ -85,15 +87,17 @@ public final class VolumeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateVolume() {
|
private void updateVolume() {
|
||||||
volumeSubject.onNext(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
|
volumeSubject.onNext(getVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVolume(final int value) {
|
public void setVolume(final int value) {
|
||||||
if (value < 0 || value > maxVolume) {
|
if (value < 0 || value > maxVolume) {
|
||||||
throw new IllegalStateException("Volume: " + value + " out of bounds [0," + maxVolume + "]");
|
Lc.fatalException(new ShouldNotHappenException("Volume: " + value + " out of bounds [0," + maxVolume + "]"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (getVolume() != value) {
|
if (getVolume() != value) {
|
||||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, value, 0);
|
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, value, 0);
|
||||||
|
updateVolume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,13 +111,13 @@ public final class VolumeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachSeekBar(@NonNull final SeekBar seekBar) {
|
public void attachSeekBar(@NonNull final SeekBar seekBar) {
|
||||||
if (this.seekBar != null) {
|
if (seekBars.containsKey(seekBar)) {
|
||||||
throw new IllegalArgumentException("Attached SeekBar is not null");
|
Lc.fatalException(new ShouldNotHappenException("SeekBar already attached"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.seekBar = seekBar;
|
seekBar.setMax(maxVolume);
|
||||||
this.seekBar.setMax(maxVolume);
|
seekBar.setProgress(getVolume());
|
||||||
this.seekBar.setProgress(getVolume());
|
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
this.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser) {
|
public void onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser) {
|
||||||
|
|
@ -132,52 +136,81 @@ public final class VolumeController {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
seekBarSubscription = observeVolume()
|
seekBars.put(seekBar, observeVolume()
|
||||||
.subscribeOn(AndroidSchedulers.mainThread())
|
.subscribeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(seekBar::setProgress);
|
.subscribe(seekBar::setProgress));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detachSeekBar(@NonNull final SeekBar seekBar) {
|
public void detachSeekBar(@NonNull final SeekBar seekBar) {
|
||||||
if (this.seekBar != seekBar) {
|
final Subscription subscription = seekBars.get(seekBar);
|
||||||
throw new IllegalArgumentException("Wrong SeekBar: " + seekBar + " != " + this.seekBar);
|
if (subscription == null) {
|
||||||
|
Lc.fatalException(new ShouldNotHappenException("SeekBar not attached yet"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (seekBarSubscription == null) {
|
seekBar.setOnSeekBarChangeListener(null);
|
||||||
throw new IllegalStateException("SeekBarSubscription is null on detach of SeekBar");
|
subscription.unsubscribe();
|
||||||
}
|
seekBars.remove(seekBar);
|
||||||
|
|
||||||
this.seekBar.setOnSeekBarChangeListener(null);
|
|
||||||
seekBarSubscription.unsubscribe();
|
|
||||||
seekBarSubscription = null;
|
|
||||||
this.seekBar = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachVolumeButtons(@NonNull final ImageView volumeDown, @NonNull final ImageView volumeUp) {
|
@SuppressWarnings("PMD.AccessorClassGeneration")
|
||||||
if (this.volumeDown != null && this.volumeUp != null) {
|
public void attachVolumeButtons(@NonNull final View volumeUpButton, @NonNull final View volumeDownButton) {
|
||||||
throw new IllegalArgumentException("Attached volume buttons is not null");
|
final VolumeButtons volumeButtons = new VolumeButtons(volumeUpButton, volumeDownButton);
|
||||||
|
if (volumeButtonsSet.contains(volumeButtons)) {
|
||||||
|
Lc.fatalException(new ShouldNotHappenException("VolumeButtons already attached"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
this.volumeDown = volumeDown;
|
|
||||||
this.volumeUp = volumeUp;
|
|
||||||
|
|
||||||
volumeUp.setOnClickListener(v -> {
|
volumeButtons.volumeUpButton.setOnClickListener(v -> {
|
||||||
if (getVolume() != maxVolume) {
|
if (getVolume() != maxVolume) {
|
||||||
setVolume(getVolume() + 1);
|
setVolume(getVolume() + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
volumeDown.setOnClickListener(v -> {
|
volumeButtons.volumeDownButton.setOnClickListener(v -> {
|
||||||
if (getVolume() != 0) {
|
if (getVolume() != 0) {
|
||||||
setVolume(getVolume() - 1);
|
setVolume(getVolume() - 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
volumeButtonsSet.add(volumeButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detachVolumeButtons(@NonNull final ImageView volumeDownImageView, @NonNull final ImageView volumeUpImageView) {
|
@SuppressWarnings("PMD.AccessorClassGeneration")
|
||||||
if (this.volumeDown != volumeDownImageView && this.volumeUp != volumeUpImageView) {
|
public void detachVolumeButtons(@NonNull final View volumeUpButton, @NonNull final View volumeDownButton) {
|
||||||
throw new IllegalArgumentException("Wrong SeekBar: " + seekBar + " != " + this.seekBar);
|
final VolumeButtons volumeButtons = new VolumeButtons(volumeUpButton, volumeDownButton);
|
||||||
|
if (!volumeButtonsSet.contains(volumeButtons)) {
|
||||||
|
Lc.fatalException(new ShouldNotHappenException("VolumeButtons not attached yet"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeButtons.volumeUpButton.setOnClickListener(null);
|
||||||
|
volumeButtons.volumeDownButton.setOnClickListener(null);
|
||||||
|
volumeButtonsSet.remove(volumeButtons);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class VolumeButtons {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final View volumeUpButton;
|
||||||
|
@NonNull
|
||||||
|
private final View volumeDownButton;
|
||||||
|
|
||||||
|
private VolumeButtons(@NonNull final View volumeUpButton, @NonNull final View volumeDownButton) {
|
||||||
|
this.volumeUpButton = volumeUpButton;
|
||||||
|
this.volumeDownButton = volumeDownButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object object) {
|
||||||
|
return object instanceof VolumeButtons
|
||||||
|
&& ((VolumeButtons) object).volumeDownButton == volumeDownButton
|
||||||
|
&& ((VolumeButtons) object).volumeUpButton == volumeUpButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return volumeDownButton.hashCode() + volumeUpButton.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.volumeDown = null;
|
|
||||||
this.volumeUp = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class VolumeObserver extends ContentObserver {
|
private class VolumeObserver extends ContentObserver {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
package org.roboswag.components.navigation;
|
package org.roboswag.components.navigation;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -62,6 +65,22 @@ public abstract class AbstractBaseActivity extends AppCompatActivity
|
||||||
return topFragmentTag != null && topFragmentTag.contains(TOP_FRAGMENT_TAG_MARK);
|
return topFragmentTag != null && topFragmentTag.contains(TOP_FRAGMENT_TAG_MARK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://code.google.com/p/android/issues/detail?id=2373
|
||||||
|
// https://github.com/cleverua/android_startup_activity
|
||||||
|
// http://stackoverflow.com/questions/4341600/how-to-prevent-multiple-instances-of-an-activity-when-it-is-launched-with-differ
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public boolean isLaunchedManyTimes() {
|
||||||
|
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
for (final ActivityManager.RunningTaskInfo taskInfo : activityManager.getRunningTasks(Integer.MAX_VALUE)) {
|
||||||
|
if (getPackageName().equals(taskInfo.baseActivity.getPackageName())
|
||||||
|
&& taskInfo.numActivities > 1
|
||||||
|
&& Intent.ACTION_MAIN.equals(getIntent().getAction())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue