今天我們開始進(jìn)入講解android中的一些高級(jí)主題的用法,比如傳感器、GPS、NFC、語(yǔ)音和人臉識(shí)別等。
這次來(lái)對(duì)傳感器的一個(gè)簡(jiǎn)單介紹:
Android平臺(tái)支持三大類的傳感器:
位移傳感器
這些傳感器測(cè)量沿三個(gè)軸線測(cè)量加速度和旋轉(zhuǎn)。這類包含加速度,重力傳感器,陀螺儀,和矢量傳感器。
環(huán)境傳感器
這些傳感器測(cè)量各種環(huán)境參數(shù),例如周圍的空氣溫度和壓力,光線,和濕度。這類包含氣壓,光線,和溫度傳感器。
位置傳感器
這些傳感器測(cè)量設(shè)備的物理位置。這類包含方向和磁力傳感器。
這些傳感器的一些是基于硬件的,一些是基于軟件的。基于硬件的傳感器是內(nèi)嵌到手機(jī)或者平板中的物理元件,它們通過(guò)直接測(cè)量指定的環(huán)境屬性來(lái)得到它們的數(shù)據(jù),例如加速度,磁場(chǎng)強(qiáng)度,或者角度變化?;谲浖膫鞲衅鞑皇俏锢碓O(shè)備,盡管它們模仿基于硬件的傳感器?;谲浖?傳感器從一個(gè)或更多基于硬件的傳感器獲取它們的數(shù)據(jù),并且有時(shí)候被稱為虛擬傳感器或者合成傳感器。線性加速度傳感器和重力傳感器是基于軟件傳感器的例子。
很少Android設(shè)備有所有類型的傳感器。例如,大部分手機(jī)和平板有一個(gè)加速計(jì)和磁場(chǎng)計(jì),但是很少的設(shè)備擁有氣壓或者溫度傳感器。并且,一個(gè)設(shè)備可以擁有一個(gè)類型不止一個(gè)的傳感器。例如,設(shè)備能有兩個(gè)重力傳感器,每個(gè)有不同的范圍。
需要指出的是,傳感器的坐標(biāo)系統(tǒng)與屏幕坐標(biāo)系統(tǒng)不同,傳感器坐標(biāo)系統(tǒng)的X軸沿屏幕向右;Y軸則沿屏幕向上,Z軸在垂直屏幕向上。
我們依次看看幾種傳感器:
1 加速度傳感器
加速度傳感器又叫G-sensor,返回x、y、z三軸的加速度數(shù)值。
該數(shù)值包含地心引力的影響,單位是m/s^2。
將手機(jī)平放在桌面上,x軸默認(rèn)為0,y軸默認(rèn)0,z軸默認(rèn)9.81。
將手機(jī)朝下放在桌面上,z軸為-9.81。
將手機(jī)向左傾斜,x軸為正值。
將手機(jī)向右傾斜,x軸為負(fù)值。
將手機(jī)向上傾斜,y軸為負(fù)值。
將手機(jī)向下傾斜,y軸為正值。
2 磁力傳感器
磁力傳感器簡(jiǎn)稱為M-sensor,返回x、y、z三軸的環(huán)境磁場(chǎng)數(shù)據(jù)。
該數(shù)值的單位是微特斯拉(micro-Tesla),用uT表示。
單位也可以是高斯(Gauss),1Tesla=10000Gauss。
硬件上一般沒(méi)有獨(dú)立的磁力傳感器,磁力數(shù)據(jù)由電子羅盤傳感器提供(E-compass)。
電子羅盤傳感器同時(shí)提供下文的方向傳感器數(shù)據(jù)。
3 方向傳感器
方向傳感器簡(jiǎn)稱為O-sensor,返回三軸的角度數(shù)據(jù),方向數(shù)據(jù)的單位是角度。
為了得到精確的角度數(shù)據(jù),E-compass需要獲取G-sensor的數(shù)據(jù),
經(jīng)過(guò)計(jì)算生產(chǎn)O-sensor數(shù)據(jù),否則只能獲取水平方向的角度。
方向傳感器提供三個(gè)數(shù)據(jù),分別為azimuth、pitch和roll。
azimuth:方位,以z軸為軸,返回水平時(shí)磁北極和Y軸的夾角,范圍為0°至360°。
0°=北,90°=東,180°=南,270°=西。
pitch:x軸和水平面的夾角,范圍為-180°至180°。
當(dāng)z軸向y軸轉(zhuǎn)動(dòng)時(shí),角度為正值。
roll:y軸和水平面的夾角,由于歷史原因,范圍為-90°至90°。
當(dāng)x軸向z軸移動(dòng)時(shí),角度為正值。
4 陀螺儀傳感器
陀螺儀傳感器叫做Gyro-sensor,返回x、y、z三軸的角加速度數(shù)據(jù)。
角加速度的單位是radians/second。
根據(jù)Nexus S手機(jī)實(shí)測(cè):
水平逆時(shí)針旋轉(zhuǎn),Z軸為正。
水平逆時(shí)針旋轉(zhuǎn),z軸為負(fù)。
向左旋轉(zhuǎn),y軸為負(fù)。
向右旋轉(zhuǎn),y軸為正。
向上旋轉(zhuǎn),x軸為負(fù)。
向下旋轉(zhuǎn),x軸為正。
5 光線感應(yīng)傳感器
光線感應(yīng)傳感器檢測(cè)實(shí)時(shí)的光線強(qiáng)度,光強(qiáng)單位是lux,其物理意義是照射到單位面積上的光通量。
光線感應(yīng)傳感器主要用于Android系統(tǒng)的LCD自動(dòng)亮度功能。
可以根據(jù)采樣到的光強(qiáng)數(shù)值實(shí)時(shí)調(diào)整LCD的亮度。
6 壓力傳感器
壓力傳感器返回當(dāng)前的壓強(qiáng),單位是百帕斯卡hectopascal(hPa)。
7 溫度傳感器
溫度傳感器返回當(dāng)前的溫度。
8 距離傳感器
距離傳感器檢測(cè)物體與手機(jī)的距離,單位是厘米。
一些距離傳感器只能返回遠(yuǎn)和近兩個(gè)狀態(tài),
因此,距離傳感器將最大距離返回遠(yuǎn)狀態(tài),小于最大距離返回近狀態(tài)。
距離傳感器可用于接聽(tīng)電話時(shí)自動(dòng)關(guān)閉LCD屏幕以節(jié)省電量。
一些芯片集成了距離傳感器和光線傳感器兩者功能。
下面三個(gè)傳感器做個(gè)比較:
重力傳感器
重力傳感器簡(jiǎn)稱GV-sensor,輸出重力數(shù)據(jù)。
在地球上,重力數(shù)值為9.8,單位是m/s^2。
坐標(biāo)系統(tǒng)與加速度傳感器相同。
當(dāng)設(shè)備復(fù)位時(shí),重力傳感器的輸出與加速度傳感器相同。
線性加速度傳感器
線性加速度傳感器簡(jiǎn)稱LA-sensor。
線性加速度傳感器是加速度傳感器減去重力影響獲取的數(shù)據(jù)。
單位是m/s^2,坐標(biāo)系統(tǒng)與加速度傳感器相同。
加速度傳感器、重力傳感器和線性加速度傳感器的計(jì)算公式如下:
加速度 = 重力 + 線性加速度
旋轉(zhuǎn)矢量傳感器
旋轉(zhuǎn)矢量傳感器簡(jiǎn)稱RV-sensor。
旋轉(zhuǎn)矢量代表設(shè)備的方向,是一個(gè)將坐標(biāo)軸和角度混合計(jì)算得到的數(shù)據(jù)。
RV-sensor輸出三個(gè)數(shù)據(jù):
x*sin(theta/2)
y*sin(theta/2)
z*sin(theta/2)
sin(theta/2)是RV的數(shù)量級(jí)。
RV的方向與軸旋轉(zhuǎn)的方向相同。
RV的三個(gè)數(shù)值,與cos(theta/2)組成一個(gè)四元組。
RV的數(shù)據(jù)沒(méi)有單位,使用的坐標(biāo)系與加速度相同。
傳感器框架:
你能訪問(wèn)這些傳感器,是通過(guò)使用Android傳感器框架獲取原始數(shù)據(jù)。Android傳感器框架式android.hardware包的一部分,包含下面的類和接口:
SensorManager
你能使用這個(gè)類來(lái)創(chuàng)建一個(gè)傳感器服務(wù)的實(shí)例。這個(gè)類提供了各種方法類訪問(wèn)和列舉傳感器,注冊(cè)和注銷傳感器事件監(jiān)聽(tīng),并獲取相應(yīng)的信息。這個(gè)類也提供了幾個(gè)傳感器的常量,用戶報(bào)告?zhèn)鞲衅鞯木_度,設(shè)置數(shù)據(jù)獲取速率,和校準(zhǔn)傳感器。
Sensor
你能使用這個(gè)類來(lái)創(chuàng)建一個(gè)指定傳感器的實(shí)例。這個(gè)類提供了各種方法讓你確定傳感器的功能。
SensorEvent
它提供了關(guān)于傳感器事件的信息。一個(gè)傳感器事件包含以下信息:原始傳感器數(shù)據(jù),這類傳感器產(chǎn)生的事件,數(shù)據(jù)的準(zhǔn)確性,和事件的時(shí)間戳。
SensorEventListener
你能使用這個(gè)接口來(lái)創(chuàng)建兩個(gè)回調(diào)方法,當(dāng)傳感器的值改變或者當(dāng)傳感器的精度改變的時(shí)候,它接受通知(傳感器事件)。
傳感器的值改變
在這種情況下系統(tǒng)調(diào)用onSensorChanged()方法,向你提供了一個(gè)SensorEvent對(duì)象,一個(gè)SensorEvent對(duì)象包含關(guān)于新的傳感器數(shù)據(jù)的信息,包括:數(shù)據(jù)的精度,傳感器產(chǎn)生的數(shù)據(jù),數(shù)據(jù)產(chǎn)生的時(shí)間戳,和傳感器記錄的新的數(shù)據(jù)。
傳感器精度的變化
在 這種情況下系統(tǒng)調(diào)用onAccuracyChanged()方法,向你提供改變了新的傳感器精度的Sensor對(duì)象引用。精度通過(guò)四個(gè)狀態(tài)常量代 表:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH, 或者SENSOR_STATUS_UNRELIABLE。
使用傳感器的步驟如下:
?、僬{(diào)用Context的getSystemService(Context.SENSOR_SERVICE)方法獲取SensorManager對(duì)象。
?、谡{(diào)用SensorManager的getDefaultSensor(int type)方法來(lái)獲取指定類型的傳感器。
從傳感器管理器中獲取其中某個(gè)或者某些傳感器的方法有如下三種:
第一種:獲取某種傳感器的默認(rèn)傳感器
Sensor defaultGyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
第二種:獲取某種傳感器的列表
List《Sensor》 pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);
第三種:獲取所有傳感器的列表,我們這個(gè)例子就用的第三種
List《Sensor》 allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
③一般在Activity的onResume()方法中調(diào)用SensorManager的registerListener()為指定傳感器注冊(cè)監(jiān)聽(tīng)器即可。程序可以通過(guò)實(shí)現(xiàn)監(jiān)聽(tīng)器即可獲取傳感器傳回來(lái)的數(shù)據(jù)。
SersorManager提供的注冊(cè)傳感器的方法為registerListener(SensorListener listener, Sensor sensor, int rate)該方法中三個(gè)參數(shù)說(shuō)明如下:
listener:監(jiān)聽(tīng)傳感器事件的監(jiān)聽(tīng)器
sensor:傳感器對(duì)象
rate:指定獲取傳感器數(shù)據(jù)的頻率
rate可以獲取傳感器數(shù)據(jù)的頻率,支持如下幾個(gè)頻率值:
SENSOR_DELAY_FASTEST:最快,延遲最小。
SENSOR_DELAY_GAME:適合游戲的頻率。
SENSOR_DELAY_NORMAL:正常頻率
SENSOR_DELAY_UI:適合普通用戶界面的頻率。
那就來(lái)舉個(gè)例子來(lái)測(cè)試下:
這個(gè)例子就是顯示下手機(jī)上支持的傳感器及傳感器的一些信息并測(cè)試幾個(gè)常用傳感器
效果:
核心代碼:
activity_main.xml
《LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”
tools:context=“com.example.fenxichuanganqi.MainActivity” 》
《TextView
android:id=“@+id/tv”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“方向傳感器:”
android:textColor=“#ff0000” /》
《TextView
android:id=“@+id/tv_direction”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“線性傳感器:”
android:textColor=“#ff0000” /》
《TextView
android:id=“@+id/tv_xianxing”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“加速度傳感器:”
android:textColor=“#ff0000” /》
《TextView
android:id=“@+id/tv_jiasudu”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“光強(qiáng)傳感器:”
android:textColor=“#ff0000” /》
《TextView
android:id=“@+id/tv_guangqiang”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“距離傳感器:”
android:textColor=“#ff0000” /》
《TextView
android:id=“@+id/tv_juli”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content” /》
《/LinearLayout》
MainActivity.java
public class MainActivity extends Activity implements SensorEventListener{
private TextView tv;
private TextView tv_direction;
private TextView tv_xianxing;
private TextView tv_jiasudu;
private TextView tv_guangqiang;
private TextView tv_juli;
private SensorManager sensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.獲取SensorManager服務(wù)
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
tv = (TextView) findViewById(R.id.tv);
tv_direction = (TextView) findViewById(R.id.tv_direction);
tv_xianxing = (TextView) findViewById(R.id.tv_xianxing);
tv_jiasudu = (TextView) findViewById(R.id.tv_jiasudu);
tv_guangqiang = (TextView) findViewById(R.id.tv_guangqiang);
tv_juli = (TextView) findViewById(R.id.tv_juli);
//獲取手機(jī)上支持的傳感器
List《Sensor》 list = sensorManager.getSensorList(Sensor.TYPE_ALL);
tv.append(“手機(jī)上有” + list.size() + “個(gè)傳感器” + “\n”);
for (Sensor sensor : list) {
String msg = “名字:” + sensor.getName() + “,版本:” + sensor.getVersion()
+“,供應(yīng)商:” + sensor.getVendor() + “,類型:” + sensor.getType();
tv.append(msg + “\n”);
}
}
@Override
protected void onResume() {
//23.獲得相應(yīng)傳感器并注冊(cè)監(jiān)聽(tīng)器
//第三個(gè)參數(shù)表示精度
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
sensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
sensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
sensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
sensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
sensorManager.SENSOR_DELAY_UI);
super.onResume();
}
@Override
protected void onStop() {
//4.解除綁定
sensorManager.unregisterListener(this);
super.onStop();
}
@Override
public void onSensorChanged(SensorEvent event) {
//傳感器數(shù)據(jù)變化,在該方法中我們可以獲取傳感器變化的值
switch (event.sensor.getType()) {
case Sensor.TYPE_ORIENTATION:
float z = event.values[0];
float x = event.values[1];
float y = event.values[2];
tv_direction.setText(“z軸的方向:” + z + “\n”
+ “x軸的方向:” + x + “\n”
+ “y軸的方向:” + y + “\n”);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
float x1 = event.values[0];
float y1 = event.values[1];
float z1 = event.values[2];
tv_xianxing.setText(“x軸的加速度:” + x1 + “\n”
+ “y軸的加速度:” + y1 + “\n”
+ “z軸的加速度:” + z1 + “\n”);
break;
case Sensor.TYPE_ACCELEROMETER:
float x2 = event.values[0];
float y2 = event.values[1];
float z2 = event.values[2];
tv_jiasudu.setText(“x軸的加速度:” + x2 + “\n”
+ “y軸的加速度:” + y2 + “\n”
+ “z軸的加速度:” + z2 + “\n”);
break;
case Sensor.TYPE_LIGHT:
float light = event.values[0];
tv_guangqiang.setText(“光強(qiáng):” + light);
break;
case Sensor.TYPE_PROXIMITY:
float distanse = event.values[0];
tv_juli.setText(“距離傳感器:” + distanse);
break;
default:
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//傳感器精度的變化
}
}
這個(gè)傳感器的介紹就這些,大家應(yīng)該都看得懂。趕緊拿出自己的手機(jī)來(lái)試試吧。