From 8900b0fa4a03cd7d08505129a3bfcb4cfc3171fb Mon Sep 17 00:00:00 2001 From: seven332 Date: Mon, 21 Mar 2016 18:04:46 +0800 Subject: [PATCH] Shake device to clear pattern protection --- .../ehviewer/ui/scene/SecurityScene.java | 64 +++++++++++++++- .../com/hippo/hardware/ShakeDetector.java | 73 +++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/hippo/hardware/ShakeDetector.java diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java index 2cd9117c6..561b374e5 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SecurityScene.java @@ -16,6 +16,9 @@ package com.hippo.ehviewer.ui.scene; +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorManager; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.LayoutInflater; @@ -25,14 +28,17 @@ import android.view.ViewGroup; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; import com.hippo.ehviewer.ui.MainActivity; +import com.hippo.hardware.ShakeDetector; import com.hippo.widget.lockpattern.LockPatternUtils; import com.hippo.widget.lockpattern.LockPatternView; +import com.hippo.yorozuya.AssertUtils; import com.hippo.yorozuya.ObjectUtils; import com.hippo.yorozuya.ViewUtils; import java.util.List; -public class SecurityScene extends BaseScene implements LockPatternView.OnPatternListener { +public class SecurityScene extends BaseScene implements + LockPatternView.OnPatternListener, ShakeDetector.OnShakeListener { private static final int MAX_RETRY_TIMES = 5; @@ -41,11 +47,27 @@ public class SecurityScene extends BaseScene implements LockPatternView.OnPatter @Nullable private LockPatternView mPatternView; + private SensorManager mSensorManager; + private Sensor mAccelerometer; + private ShakeDetector mShakeDetector; + private int mRetryTimes; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + Context context = getContext2(); + AssertUtils.assertNotNull(context); + mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + if (null != mSensorManager) { + mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (null != mAccelerometer) { + mShakeDetector = new ShakeDetector(); + mShakeDetector.setOnShakeListener(this); + } + } + if (null == savedInstanceState) { mRetryTimes = MAX_RETRY_TIMES; } else { @@ -53,6 +75,33 @@ public class SecurityScene extends BaseScene implements LockPatternView.OnPatter } } + @Override + public void onDestroy() { + super.onDestroy(); + + mSensorManager = null; + mAccelerometer = null; + mShakeDetector = null; + } + + @Override + public void onResume() { + super.onResume(); + + if (null != mShakeDetector) { + mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI); + } + } + + @Override + public void onPause() { + super.onPause(); + + if (null != mShakeDetector) { + mSensorManager.unregisterListener(mShakeDetector); + } + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -108,4 +157,17 @@ public class SecurityScene extends BaseScene implements LockPatternView.OnPatter } } } + + @Override + public void onShake(int count) { + if (count == 10) { + MainActivity activity = getActivity2(); + if (null == activity) { + return; + } + Settings.putSecurity(""); + activity.startSceneForCheckStep(MainActivity.CHECK_STEP_SECURITY, getArguments()); + finish(); + } + } } diff --git a/app/src/main/java/com/hippo/hardware/ShakeDetector.java b/app/src/main/java/com/hippo/hardware/ShakeDetector.java new file mode 100644 index 000000000..c7ea7f980 --- /dev/null +++ b/app/src/main/java/com/hippo/hardware/ShakeDetector.java @@ -0,0 +1,73 @@ +package com.hippo.hardware; + +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +// http://jasonmcreynolds.com/?p=388 +public class ShakeDetector implements SensorEventListener { + + /* + * The gForce that is necessary to register as shake. + * Must be greater than 1G (one earth gravity unit). + * You can install "G-Force", by Blake La Pierre + * from the Google Play Store and run it to see how + * many G's it takes to register a shake + */ + private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F; + private static final int SHAKE_SLOP_TIME_MS = 500; + private static final int SHAKE_COUNT_RESET_TIME_MS = 3000; + + private OnShakeListener mListener; + private long mShakeTimestamp; + private int mShakeCount; + + public void setOnShakeListener(OnShakeListener listener) { + mListener = listener; + } + + public interface OnShakeListener { + void onShake(int count); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // ignore + } + + @Override + public void onSensorChanged(SensorEvent event) { + + if (mListener != null) { + float x = event.values[0]; + float y = event.values[1]; + float z = event.values[2]; + + float gX = x / SensorManager.GRAVITY_EARTH; + float gY = y / SensorManager.GRAVITY_EARTH; + float gZ = z / SensorManager.GRAVITY_EARTH; + + // gForce will be close to 1 when there is no movement. + float gForce = (float) Math.sqrt(gX * gX + gY * gY + gZ * gZ); + + if (gForce > SHAKE_THRESHOLD_GRAVITY) { + final long now = System.currentTimeMillis(); + // ignore shake events too close to each other (500ms) + if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) { + return; + } + + // reset the shake count after 3 seconds of no shakes + if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) { + mShakeCount = 0; + } + + mShakeTimestamp = now; + mShakeCount++; + + mListener.onShake(mShakeCount); + } + } + } +}