一.Android的三大類傳感器
Android傳感器按大方向劃分大致有這么三類傳感器:動作(Motion)傳感器(來回?fù)u動,動一動)、環(huán)境(Environmental)傳感器(溫度,濕度,廣感)、位置(Position)傳感器(定位)。
(1)動作傳感器
這類傳感器在三個軸(x、y、z)上測量加速度和旋轉(zhuǎn)角度。包括如下幾個傳感器:
加速(accelerometer)傳感器:(手機(jī)搖一搖)
重力(gravity)傳感器、(憤怒的小鳥)
陀螺儀(gyroscope)傳感器、(指南針,還有我們以前玩的小游戲,通過手機(jī)控制方向玩摩托車)
旋轉(zhuǎn)向量(rotational vector )傳感器(比如我們做地圖的那個小圖標(biāo),你轉(zhuǎn)一下,手機(jī)也轉(zhuǎn)一下)
下面來看一下傳感器世界的坐標(biāo)系:

(2)環(huán)境傳感器
這類傳感器可以測量不同環(huán)境的參數(shù),例如,周圍環(huán)境的空氣溫度和壓強(qiáng)、光照強(qiáng)度和濕度。包括如下幾個傳感器:
濕度(barometer)傳感器、光線(photometer)傳感器、溫度(thermometer)傳感器
(3)位置傳感器
這類傳感器可以測量設(shè)備的物理位置。包括如下幾個傳感器:
方向(orientation)傳感器(指南針除了用陀螺儀還要用方向)
磁力(magnetometer)傳感器(指南針的南北極)
二.Android傳感器的框架
了解后我們就開始進(jìn)入傳感器的編程工作了,接下來我們看一下Android為我們提供的傳感器框架(Android sensor framework,簡稱ASF)。
android傳感器有很多種,不同的設(shè)備上可能有不同的傳感器,android系統(tǒng)中有一個專門管理傳感器的對象
獲取手機(jī)的傳感器
通過實例化的SensorManager可以獲取到手機(jī)的傳感器集合
//獲取傳感器SensorManager對象
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : sensors) {
tvSensors.append(sensor.getName() + "\n");
}
Android對每個設(shè)備的傳感器都進(jìn)行了抽象,其中SensorManger類用來控制傳感器,Sensor用來描述具體的傳感器,SensorEventListener用來監(jiān)聽傳感器值的改變。
(1)SensorManager類(就相當(dāng)于領(lǐng)導(dǎo))
用于創(chuàng)建sensor service的實例。該類提供了很多用于訪問和枚舉傳感器,注冊和注銷傳感器監(jiān)聽器的方法。而且還提供了與傳感器精度、掃描頻率、校正有關(guān)的常量。
(2)Sensor類
Sensor類為我們提供了一些用于獲取傳感器技術(shù)參數(shù)的方法。如版本、類型、生產(chǎn)商等。例如所有傳感器的TYPE類型如下:

(3)SensorEvent類
系統(tǒng)使用該類創(chuàng)建傳感器事件對象。該對象可以提供與傳感器事件有關(guān)的信息。傳感器事件對象包括的信息有原始的傳感器回傳數(shù)據(jù)、傳感器類型、數(shù)據(jù)的精度以及觸發(fā)事件的時間。
(4)SensorEventListener接口
該接口包含兩個回調(diào)方法,當(dāng)傳感器的回傳值或精度發(fā)生變化時,系統(tǒng)會調(diào)用這兩個回調(diào)方法。
/**
* 傳感器精度變化時回調(diào)
* */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/*
* 傳感器數(shù)據(jù)變化時回調(diào)
*/
@Override
public void onSensorChanged(SensorEvent event) {
}
三.獲取傳感器技術(shù)參數(shù)
下來我們編寫代碼來獲取一下自己手機(jī)的傳感器技術(shù)參數(shù)
//獲取傳感器SensorManager對象
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
for (Sensor sensor : sensors) { tvSensors.append(sensor.getName() + "\n");
}
各種傳感器的使用:
1.加速度傳感器
//創(chuàng)建一個SensorManager來獲取系統(tǒng)的傳感器服務(wù)
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
/*
* 最常用的一個方法 注冊事件
* 參數(shù)1 :SensorEventListener監(jiān)聽器
* 參數(shù)2 :Sensor 一個服務(wù)可能有多個Sensor實現(xiàn),此處調(diào)用getDefaultSensor獲取默認(rèn)的Sensor
* 參數(shù)3 :模式 可選數(shù)據(jù)變化的刷新頻率,多少微秒取一次。
* */
//加速度傳感器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
接下來我們只要監(jiān)聽這個傳感器值的變化,然后更新textView的值就好了
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float X_lateral = sensorEvent.values[0];
float Y_longitudinal = sensorEvent.values[1];
float Z_vertical = sensorEvent.values[2];
mtextViewx.setText(X_lateral + "");
mtextViewy.setText(Y_longitudinal + "");
mtextViewz.setText(Z_vertical + "");
}
}
在activity變?yōu)椴豢梢姷臅r候,傳感器依然在工作,這樣很耗電,所以我們根據(jù)需求可以在onStop方法里面停掉傳感器的工作
@Override
public void onStop() {
sm.unregisterListener(this);
super.onStop();
}
2.磁場傳感器
和加速度計一樣,為sensormanager監(jiān)聽磁場變化即可,把手機(jī)放在電腦旁邊時候可以清楚看到數(shù)值的變化
// 為磁場傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD){
float X_lateral = sensorEvent.values[0];
float Y_longitudinal = sensorEvent.values[1];
float Z_vertical = sensorEvent.values[2];
mtextView1.setText("x軸的磁場強(qiáng)度\n"+ X_lateral );
mtextView2.setText("y軸的磁場強(qiáng)度\n"+ Y_longitudinal );
mtextView3.setText("z軸的磁場強(qiáng)度\n"+ Z_vertical );
}
3.方向傳感器
這個可以用來做指南針之類的,繞z軸轉(zhuǎn)過的角度為0時大概指向正北。這個TYPE_ORIENTATION接口不夠精確已經(jīng)過時了,可以使用旋轉(zhuǎn)矩陣來代替。這里繞z軸轉(zhuǎn)過的角度是value[0],看源碼可得
// 為方向傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION){
float X_lateral = sensorEvent.values[0];
float Y_longitudinal = sensorEvent.values[1];
float Z_vertical = sensorEvent.values[2];
mtextView4.setText("繞z軸轉(zhuǎn)過的角度\n"+ X_lateral );
mtextView5.setText("繞x軸轉(zhuǎn)過的角度\n"+ Y_longitudinal );
mtextView6.setText("繞y軸轉(zhuǎn)過的角度\n"+ Z_vertical );
}
4.陀螺儀傳感器
// 為陀螺儀傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_GYROSCOPE){
//需要將弧度轉(zhuǎn)為角度
float X = (float)Math.toDegrees(sensorEvent.values[0]);
float Y = (float)Math.toDegrees(sensorEvent.values[1]);
float Z = (float)Math.toDegrees(sensorEvent.values[2]);
mtextView7.setText("繞x軸轉(zhuǎn)過的角速度\n"+ X );
mtextView8.setText("繞y軸轉(zhuǎn)過的角速度\n"+ Y );
mtextView9.setText("繞z軸轉(zhuǎn)過的角速度\n"+ Z );
}
5.重力傳感器
就是把重力加速度分解到xyz三個方向上
// 為重力傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_GRAVITY){
float X = sensorEvent.values[0];
float Y = sensorEvent.values[1];
float Z = sensorEvent.values[2];
mtextViewgx.setText("x方向的重力加速度\n"+ X );
mtextViewgy.setText("Y方向的重力加速度\n"+ Y );
mtextViewgz.setText("Z方向的重力加速度\n"+ Z );
6.線性加速度傳感器
就是去掉重力加速度后各個方向的加速度
// 為線性加速度傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION){
float X = sensorEvent.values[0];
float Y = sensorEvent.values[1];
float Z = sensorEvent.values[2];
mtextViewlx.setText("x方向的線性加速度\n"+ X );
mtextViewly.setText("Y方向的線性加速度\n"+ Y );
mtextViewlz.setText("Z方向的線性加速度\n"+ Z );
}
7.溫度傳感器
這里的TYPE_TEMPERATURE已經(jīng)過時,測出來的是cpu的溫度,所以測出來的數(shù)值有點大,如果測環(huán)境溫度的話應(yīng)該使用
TYPE_AMBIENT_TEMPERATURE。不過大部分手機(jī)都沒有這個傳感器
// 為溫度傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_TEMPERATURE), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_TEMPERATURE){
float X = sensorEvent.values[0];
mtextView10.setText("溫度為"+ X );
}
8.光傳感器
// 為光傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_LIGHT){
float X = sensorEvent.values[0];
mtextView11.setText("光強(qiáng)度為為"+ X );
}
9.距離傳感器
可以控制手機(jī)打電話時候息屏,如果使用光線傳感器的話在黑夜中打電話就自動息屏了
// 為距離傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_PROXIMITY), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY){
float X = sensorEvent.values[0];
mtextView12.setText("距離為"+ X );
}
10.壓力傳感器
// 為壓力傳感器注冊監(jiān)聽器
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_PRESSURE){
float X = sensorEvent.values[0];
mtextView13.setText("壓強(qiáng)為"+ X );
}
11.計步傳感器
有兩個接口,一個Counter統(tǒng)計的是總步數(shù),而DETECTOR為該計步是否有效,有效的話就置1
// 計步統(tǒng)計
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_NORMAL);
// 單次計步
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR), SensorManager.SENSOR_DELAY_NORMAL);
else if(sensorEvent.sensor.getType() == Sensor.TYPE_STEP_COUNTER){
float X = sensorEvent.values[0];
mtextView14.setText("COUNTER:"+ X );
} else if(sensorEvent.sensor.getType() == Sensor.TYPE_STEP_DETECTOR){
//檢測到走動時值為1
float X = sensorEvent.values[0];
mtextView15.setText("DECTOR:"+ X );
}