Як відловити шейк-подію (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) {
		}
	};
}

Напишіть перше повідомлення!

Ви повинні увійти під своїм аккаунтом щоб залишати коментарі