I am writing one application. I need to define a “shake” device. How to implement it?
1 answer
- Add to the manifest an indication of the use of the sensor - accelerometer
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" /> - Create a class that implements the
SensorEventListenerinterface in theSensorEventListenermethodonSensorChangedhandle the sensor readings. For example:
import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; public class ShakeDetector implements SensorEventListener { 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) { this.mListener = listener; } public interface OnShakeListener { public 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; float gForce = (float)Math.sqrt(gX * gX + gY * gY + gZ * gZ); if (gForce > SHAKE_THRESHOLD_GRAVITY) { final long now = System.currentTimeMillis(); if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) { return; } if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) { mShakeCount = 0; } mShakeTimestamp = now; mShakeCount++; mListener.onShake(mShakeCount); } } } } - Now you can use this class to show the dialog in the activation after shaking the device. To do this, create an object of the
SensorManagerclass, get an instance of theSensorclass from it, which, along with our implementation of theSensorEventListenerpass to theSensorManager#registerListener()method. Here is the activation code:
public class BaseActivity extends AppCompatActivity { private SensorManager mSensorManager; private Sensor mAccelerometer; private ShakeDetector mShakeDetector; private AlertDialog.Builder mDialogBuilder; private AlertDialog mAlertDialog; @Override public void onResume() { super.onResume(); mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI); } @Override public void onPause() { mSensorManager.unregisterListener(mShakeDetector); super.onPause(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mShakeDetector = new ShakeDetector(); mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() { @Override public void onShake(int count) { if (mAlertDialog == null || !mAlertDialog.isShowing()) { mDialogBuilder = new AlertDialog.Builder(BaseActivity.this); mDialogBuilder.setMessage("Ух-ты!") .setCancelable(false) .setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); mAlertDialog = mDialogBuilder.create(); mAlertDialog.show(); } } }); } } |