以前做的一個小應用裏面有搖一搖功能,有必要寫下來做個筆記。
搖一搖功能主要用到加速度傳感器:Sensor.TYPE_ACCELEROMETER
搖一搖功能主要是監聽手機加速度變化,當超過設定的某一值時,即觸發事件。
一、簡單的一個示例
下給出一段簡單的實現代碼:
功能:原先textview1顯示爲“初始文本”, 當搖晃之後,textview1變爲”搖一搖成功!!!“並伴隨震動(點擊按鈕可回到”初始文本“)。
public class SensorTestActivity extends Activity implements SensorEventListener
{
TextView tv = null;
Button button = null;
SensorManager sensorManager = null;
Vibrator vibrator = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.textview1);
button.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
tv.setText("初始文本");
}
});
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
}
@Override
protected void onPause()
{
super.onPause();
sensorManager.unregisterListener(this);
}
@Override
protected void onResume()
{
super.onResume();
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
//當傳感器精度改變時回調該方法,Do nothing.
}
@Override
public void onSensorChanged(SensorEvent event)
{
int sensorType = event.sensor.getType();
//values[0]:X軸,values[1]:Y軸,values[2]:Z軸
float[] values = event.values;
if (sensorType == Sensor.TYPE_ACCELEROMETER)
{
if ((Math.abs(values[0]) > 17 || Math.abs(values[1]) > 17 || Math
.abs(values[2]) > 17))
{
Log.d("sensor x ", "============ values[0] = " + values[0]);
Log.d("sensor y ", "============ values[1] = " + values[1]);
Log.d("sensor z ", "============ values[2] = " + values[2]);
tv.setText("搖一搖成功!!!");
//搖動手機後,再伴隨震動提示~~
vibrator.vibrate(500);
}
}
}
}
二、更加靈活一點的寫法
可以將監聽部分與註冊部分分開,這樣的好處就是實現監聽的代碼複用。
以下貼幾段以前的幾段代碼。
1. 監聽部分
public class ShakeListenerUtils implements SensorEventListener
{
private Activity context;
public ShakeListenerUtils(Activity context)
{
super();
this.context = context;
}
@Override
public void onSensorChanged(SensorEvent event)
{
int sensorType = event.sensor.getType();
//values[0]:X軸,values[1]:Y軸,values[2]:Z軸
float[] values = event.values;
if (sensorType == Sensor.TYPE_ACCELEROMETER)
{
/*正常情況下,任意軸數值最大就在9.8~10之間,只有在突然搖動手機
的時候,瞬時加速度纔會突然增大或減少。 監聽任一軸的加速度大於17即可
*/
if ((Math.abs(values[0]) > 17 || Math.abs(values[1]) > 17 || Math
.abs(values[2]) > 17))
{
context.overridePendingTransition(R.anim.zoom_out_enter,
R.anim.zoom_out_exit);
//檢測到晃動後啓動OpenDoor效果
Intent intent = new Intent(context, OpenDoorActivity.class);
context.startActivity(intent);
context.finish();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
//當傳感器精度改變時回調該方法,Do nothing.
}
}
2. 註冊部分
public class ShakeILikeActivity extends Activity
{
private ShakeListenerUtils shakeUtils;
private SensorManager mSensorManager; //定義sensor管理器, 註冊監聽器用
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shake_i_like);
shakeUtils = new ShakeListenerUtils(this);
}
@Override
protected void onResume()
{
super.onResume();
//獲取傳感器管理服務
mSensorManager = (SensorManager) this
.getSystemService(Service.SENSOR_SERVICE);
//加速度傳感器
mSensorManager.registerListener(shakeUtils,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
//還有SENSOR_DELAY_UI、SENSOR_DELAY_FASTEST、SENSOR_DELAY_GAME等,
//根據不同應用,需要的反應速率不同,具體根據實際情況設定
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause()
{
mSensorManager.unregisterListener(shakeUtils);
this.overridePendingTransition(R.anim.fade_in, R.anim.fade_out);//回退時閃一下
super.onPause();
}
}