В Android часто используемым событием является встряхивание устройства, благодаря которому происходят какие-то функции приложения, например звуковой сигнал или перерисовка экрана. В этой статье рассмотрим данное событие.
Для начала нам понадобится слушатель для событий перемещения устройства в пространстве:
private final SensorEventListener sensorListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent sensorEvent) {
float x = sensorEvent.values[0];
float y = sensorEvent.values[1];
float z = sensorEvent.values[2];
accelPrevious = accel;
accel = (float) Math.sqrt((double) (x * x + y * y + z * z));
if (accel - accelPrevious > 4) {
// SHAKE EVENT
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Принцип работы этого метода прост: вычисляется растояние, пройденное устройством в пространстве между двумя временными интервалами (двумя вызовами метода onSensorChanged()) и если это расстояние больше числа 4, то событие встряхивания произошло.
Обратите внимание на комментарий метода onSensorChanged():
// SHAKE EVENT
Именно на месте комментария происходит событие встряхивания. Вы можете изменять чувствительность, используя число в условии:
if (accel - accelPrevious > 4) {
...
}
Чем меньше число, тем более чувствительно устройство к встряхиванию. И наоборот, чем больше число, тем менее чувствительно.
Также необходимо подключить вышеописанный слушатель к Activity. Сделать это необходимо в трёх методах: onCreate(), onResume() и onStop():
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(
sensorListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(
sensorListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onStop() {
sensorManager.unregisterListener(sensorListener);
super.onStop();
}
Полный пример Activity приведен ниже:
package com.seostella.shake;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
public class ShakeActivity extends Activity {
private static final String TAG = "ShakeActivity";
private static final int SHAKE_SENSITIVITY = 4;
private SensorManager sensorManager;
private float accel = SensorManager.GRAVITY_EARTH;
private float accelPrevious = SensorManager.GRAVITY_EARTH;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(
sensorListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(
sensorListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onStop() {
sensorManager.unregisterListener(sensorListener);
super.onStop();
}
protected void onShake(){
Log.d(TAG, "SHAKE");
}
private final SensorEventListener sensorListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent sensorEvent) {
float x = sensorEvent.values[0];
float y = sensorEvent.values[1];
float z = sensorEvent.values[2];
accelPrevious = accel;
accel = (float) Math.sqrt((double) (x * x + y * y + z * z));
if (accel - accelPrevious > SHAKE_SENSITIVITY) {
onShake();
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
}