Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android搖晃檢測ShakeDetector

Android搖晃檢測ShakeDetector

編輯:關於Android編程


最近做一個程序要實現一個Shake手機的特性。

 

想到這個功能可能應用廣泛,比如搖晃手機換圖片、截圖、洗牌、結束當前程序等,所以找了些資料,並加以改進,將此功能封裝成類(ShakeDetector),方便今後使用。

 

 

搖晃檢測基於加速傳感器(Sensor.TYPE_ACCELEROMETER)。

由於重力的存在,當手機靜止放於桌面時,加速傳感器也是有加速度的。

所以,僅通過是否有加速度來判斷搖晃是不行的。

那麼,判斷加速度的變化吧。。。

在一個較短的時間間隔求出加速度的差值,跟一個指定的阈值比較,如果差值大於阈值,則認為是搖晃發生了。

ClingMarks的方法將x、y、z方向的加速度差值簡單的加起來,我認為不是很准確。

加速度是向量,求差應該是各方向的差值平方後相加,再開方。(數學忘光了,沒記錯吧。。。)

所以就有了這行代碼

package com.example.mywifi_list;

import java.util.ArrayList;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;

public class ShakeDetector implements SensorEventListener {
	/**
	 * 檢測的時間間隔
	 */
	static final int UPDATE_INTERVAL = 100;
	/**
	 * 上一次檢測的時間
	 */
	long mLastUpdateTime;
	/**
	 * 上一次檢測時,加速度在x、y、z方向上的分量,用於和當前加速度比較求差。
	 */
	float mLastX, mLastY, mLastZ;
	Context mContext;
	SensorManager mSensorManager;
	ArrayList mListeners;
	/**
	 * 搖晃檢測阈值,決定了對搖晃的敏感程度,越小越敏感。
	 */
	public int shakeThreshold = 4000;

	public ShakeDetector(Context context) {
		mContext = context;
		mSensorManager = (SensorManager) context
				.getSystemService(Context.SENSOR_SERVICE);
		mListeners = new ArrayList();
	}

	/**
	 * 當搖晃事件發生時,接收通知
	 */
	public interface OnShakeListener {
		/**
		 * 當手機搖晃時被調用
		 */
		void onShake();
	}

	/**
	 * 注冊OnShakeListener,當搖晃時接收通知
	 * 
	 * @param listener
	 */
	public void registerOnShakeListener(OnShakeListener listener) {
		if (mListeners.contains(listener))
			return;
		mListeners.add(listener);
	}

	/**
	 * 移除已經注冊的OnShakeListener
	 * 
	 * @param listener
	 */
	public void unregisterOnShakeListener(OnShakeListener listener) {
		mListeners.remove(listener);
	}

	/**
	 * 啟動搖晃檢測
	 */
	public void start() {
		if (mSensorManager == null) {
			throw new UnsupportedOperationException();
		}
		Sensor sensor = mSensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		if (sensor == null) {
			throw new UnsupportedOperationException();
		}
		boolean success = mSensorManager.registerListener(this, sensor,
				SensorManager.SENSOR_DELAY_GAME);
		if (!success) {
			throw new UnsupportedOperationException();
		}
	}

	/**
	 * 停止搖晃檢測
	 */
	public void stop() {
		if (mSensorManager != null)
			mSensorManager.unregisterListener(this);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		long currentTime = System.currentTimeMillis();
		long diffTime = currentTime - mLastUpdateTime;
		if (diffTime < UPDATE_INTERVAL)
			return;
		mLastUpdateTime = currentTime;
		float x = event.values[0];
		float y = event.values[1];
		float z = event.values[2];
		float deltaX = x - mLastX;
		float deltaY = y - mLastY;
		float deltaZ = z - mLastZ;
		mLastX = x;
		mLastY = y;
		mLastZ = z;
		float delta = FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
				* deltaZ)
				/ diffTime * 10000;
		if (delta > shakeThreshold) { // 當加速度的差值大於指定的阈值,認為這是一個搖晃
			this.notifyListeners();
		}
	}

	/**
	 * 當搖晃事件發生時,通知所有的listener
	 */
	private void notifyListeners() {
		for (OnShakeListener listener : mListeners) {
			listener.onShake();
		}
	}
}

如何使用ShakeDetector

  1. new一個ShakeDetector調用mShakeDetector.registerOnShakeListener()注冊一個OnShakeListener在OnShakeListener的onShake函數中,處理搖晃事件調用mShakeDetector.start()啟動搖晃檢測mShakeDetector.stop()用於停止搖晃檢測 我寫的時候是讓Activity implements OnShakeListener;直接在setContentView(R.layout.activity_main)後面加上
    		this.getApplicationContext();
    		mShakeDetector = new ShakeDetector(this);
    		mShakeDetector.registerOnShakeListener(this);
    		mShakeDetector.start();

    Activity在onShake()方法裡面寫搖晃的事件
    	@Override
    	public void onShake() {
    		// TODO Auto-generated method stub
    		Toast.makeText(MainActivity.this, 搖一搖!, Toast.LENGTH_LONG).show();
    	}
    停止檢測搖晃,就在onstop裡面寫上停止檢測
    	public void onStop(){
    		super.onStop();
    		mShakeDetector.stop();
     
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved