Skip to content

Instantly share code, notes, and snippets.

@Tagakov
Last active July 30, 2016 09:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Tagakov/1b9c2327be0d88844858 to your computer and use it in GitHub Desktop.
Save Tagakov/1b9c2327be0d88844858 to your computer and use it in GitHub Desktop.
Hidden button for debugging purposes. Should be used with: debugCompile 'com.squareup:seismic:1.0.2'
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.squareup.seismic.ShakeDetector;
import hugo.weaving.DebugLog;
import ru.yandex.yandexmaps.BuildConfig;
import timber.log.Timber;
/**
* Created by tagakov on 16.09.15. Hidden button for debugging purposes.
* Should be used with:
*
* debugCompile 'com.squareup:seismic:1.0.2'
*
* Typical use is:
*
* <code>
* if (BuildConfig.DEBUG) {
* Dev.init(getApplicationContext()).onShake(new Runnable() {
* @Override
* public void run() {
* //do something
* }
* }
* }
* </code>
*/
public enum Dev {
BUTTON;
private static final int SENSITIVITY = 11;
private static final long SHAKING_THRESHOLD_MS = 1500;
private static final long[] VIBRO_PATTERN = new long[]{
75, 50, 25, 0, 25, 50, 75 };
private final Handler mainThreadHandler =
new Handler(Looper.getMainLooper());
private Application application;
private Runnable onShakeRun;
private boolean shakerInitialized;
@NonNull
public Dev init(Application application) {
this.application = application;
enableShakeDetection();
return this;
}
/**
* Do some work after device shaking. If any default runnable was
* represented (see class doc) it will not be invoked while passed
* runnable is not null
*
* @param run - function that would be invoked on shake detection
* @return - self for chaining
*/
public Dev onShake(@Nullable Runnable run) {
onShakeRun = run;
return this;
}
public Runnable getOnShakeRunnable() {
return onShakeRun;
}
private void enableShakeDetection() {
if (shakerInitialized) {
return;
}
final SensorManager sensorManager = (SensorManager) application.getSystemService(Context.SENSOR_SERVICE);
if (sensorManager == null) {
return; //nothing to do here
}
try {
final ShakeDetector shakeDetector = new ShakeDetector(new ShakeDetector.Listener() {
long lastInvoked;
final Vibrator vibrator = (Vibrator) application.getSystemService(Context.VIBRATOR_SERVICE);
@Override
public void hearShake() {
if (System.currentTimeMillis() - lastInvoked > SHAKING_THRESHOLD_MS) {
shakingDetected(vibrator);
lastInvoked = System.currentTimeMillis();
}
}
});
shakeDetector.setSensitivity(SENSITIVITY);
application.registerActivityLifecycleCallbacks(new SimpleCallbackListener() {
int activityCounter;
@Override
public void onActivityStarted(Activity activity) {
try {
if (activityCounter++ == 0) {
shakeDetector.start(sensorManager);
}
} catch (Exception e) {
Timber.w(e, "Error while resuming shake detection, stop monitoring lifecycle");
application.unregisterActivityLifecycleCallbacks(this);
}
}
@Override
public void onActivityStopped(Activity activity) {
try {
if (--activityCounter == 0) {
shakeDetector.stop();
}
} catch (Exception e) {
Timber.w(e, "Error while stopping shake detection, stop monitoring lifecycle");
application.unregisterActivityLifecycleCallbacks(this);
}
}
});
shakerInitialized = true;
} catch (Throwable ignore) {
if (BuildConfig.DEBUG) {
Timber.w(ignore, "Error while enabling Dev.BUTTON");
}
//Ok we can't do the fancy stuff for debugging
}
}
@DebugLog
private void shakingDetected(Vibrator vibrator) {
if (onShakeRun != null) {
mainThreadHandler.postDelayed(
onShakeRun, 0);
if (vibrator != null && vibrator.hasVibrator()) {
try {
vibrator.vibrate(VIBRO_PATTERN, -1);
} catch (SecurityException ignore) {
//we dont have permissions
}
}
}
}
private static class SimpleCallbackListener implements Application.ActivityLifecycleCallbacks {
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override public void onActivityStarted(Activity activity) {}
@Override public void onActivityResumed(Activity activity) {}
@Override public void onActivityPaused(Activity activity) {}
@Override public void onActivityStopped(Activity activity) {}
@Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override public void onActivityDestroyed(Activity activity) {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment