最近用知乎的時(shí)候,偶然間發(fā)現(xiàn)搖一搖可以反饋問題,就想著做一個(gè)類似的功能,順便梳理下關(guān)于sensor的知識(shí)。
先看看做出來的效果:

傳感器中比較重要的幾個(gè)類:
android.hardware.Sensor;
android.hardware.SensorEvent
android.hardware.SensorEventListener
okay,會(huì)這幾個(gè)類就夠用了,再記住一個(gè)回調(diào)方法,就能對(duì)付大多數(shù)的需求了
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
}
下面讓我回顧下傳感器的知識(shí):
Android 中傳感器有很多,當(dāng)你打出[Sensor.]的時(shí)候就會(huì)看到下面這樣

下面還有好多,如果想詳細(xì)研究下所有傳感器可以看看這里 直達(dá)鏈接
Android的三大類傳感器
動(dòng)作(Motion)傳感器、環(huán)境(Environmental)傳感器、位置(Position)傳感器
1.動(dòng)作傳感器
加速(accelerometer)傳感器、重力(gravity)傳感器、陀螺儀(gyroscope)傳感器、旋轉(zhuǎn)向量(rotational vector )傳感器
我們搖一搖功能主要用的就是動(dòng)作傳感器中的加速傳感器,動(dòng)作傳感器里有一個(gè)很吊的圖,只要?jiǎng)幼鱾鞲衅骺隙ㄉ婕暗阶鴺?biāo),下圖形象的說明了這個(gè)坐標(biāo)系。

在加速傳感器中:實(shí)現(xiàn)我上方說的那個(gè)回調(diào)
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
}
其中這三個(gè)值就代表著X,Y,Z方向的值
values[0]: Acceleration minus Gx on the x-axis
values[1]: Acceleration minus Gy on the y-axis
values[2]: Acceleration minus Gz on the z-axis
2.環(huán)境傳感器
濕度(barometer)傳感器、光線(photometer)傳感器、溫度(thermometer)傳感器
3.位置傳感器
方向(orientation)傳感器、磁力(magnetometer)傳感器
如何實(shí)現(xiàn)搖一搖反饋功能
1.顯示出手機(jī)中所有的傳感器
先獲取SensorManager對(duì)象
SensorManager sensorManager = (SensorManager).getSystemService(SENSOR_SERVICE);
列出來所有的傳感器
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
為了實(shí)現(xiàn)搖一搖功能,我寫了一個(gè)叫shakeUtils工具類并且實(shí)現(xiàn)了SensorEventListener,這樣我就需要實(shí)現(xiàn)下面兩個(gè)方法
/**
* 傳感器精度變化時(shí)回調(diào)
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* 傳感器數(shù)據(jù)變化時(shí)回調(diào)
*/
@Override
public void onSensorChanged(SensorEvent event) {
int sensorType = event.sensor.getType();
float[] values = event.values;
if (sensorType == Sensor.TYPE_ACCELEROMETER) {
//這里可以調(diào)節(jié)搖一搖的靈敏度
if ((Math.abs(values[0]) > 12 || Math.abs(values[1]) > 12 || Math.abs(values[2]) > 12)) {
System.out.println("sensor value == " + " " + values[0] + " " + values[1] + " " + values[2]);
if (null != mOnShakeListener) {
mOnShakeListener.onShake();
}
}
}
if (sensorType == Sensor.TYPE_AMBIENT_TEMPERATURE) {
//todo
}
}
在主函數(shù)里主要這樣調(diào)用shakeUtils就行了:
shakeUtils = new ShakeUtils(this);
shakeUtils.setOnShakeListener(new ShakeUtils.OnShakeListener() {
@Override
public void onShake() {
Toast.makeText(MainActivity.this, "搖了搖", Toast.LENGTH_SHORT).show();
confirmDialog.setOnConfirmListener(new ConfirmDialog.OnConfirmClickListener() {
@Override
public void onFeedBack() {
gotoFeedBackActivity();
}
@Override
public void onScreenShot() {
saveScreenShoot(rootView);
}
});
confirmDialog.show();
}
});
}
有一點(diǎn)需要注意一下,我們SensorManager讓我們能拿到設(shè)備的sensors,但是當(dāng)你不用sensors的時(shí)候,當(dāng)你的activity處于pause的時(shí)候,sensor不會(huì)自動(dòng)關(guān)閉的,這就會(huì)導(dǎo)致你的電池幾個(gè)小時(shí)就會(huì)將電耗盡。例子里有一個(gè)
最后還是附上源碼,有需要的朋友可以拿去用,直達(dá)鏈接。開源讓我們不斷進(jìn)步。