Как отловить шейк-событие (Shake, встряхивание) в Android

июня
01
2012
Метки: android shake

В 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 приведен ниже:

ShakeActivity.java

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) {
		}
	};
}

Напишите первое сообщение!

Вы должны войти под своим аккаунтом чтобы оставлять комментарии