Android系統(tǒng)提供了對(duì)傳感器的支持,如果手機(jī)的硬件提供了這些傳感器的話,那么我們就可以通過(guò)代碼獲取手機(jī)外部的狀態(tài)。比如說(shuō)手機(jī)的擺放狀態(tài)、外界的磁場(chǎng)、溫度和壓力等等。
對(duì)于我們開(kāi)發(fā)者來(lái)說(shuō),開(kāi)發(fā)傳感器十分簡(jiǎn)單。只需要注冊(cè)監(jiān)聽(tīng)器,接收回調(diào)的數(shù)據(jù)就行了,下面來(lái)詳細(xì)介紹下各傳感器的開(kāi)發(fā)。
使用
第一步
// 獲取傳感器管理對(duì)象
SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);12
第二步
// 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);12
這里我們除了可以獲取加速度傳感器之外,還可以獲取其他類型的傳感器,如:
* Sensor.TYPE_ORIENTATION:方向傳感器。
* Sensor.TYPE_GYROSCOPE:陀螺儀傳感器。
* Sensor.TYPE_MAGNETIC_FIELD:磁場(chǎng)傳感器。
* Sensor.TYPE_GRAVITY:重力傳感器。
* Sensor.TYPE_LINEAR_ACCELERATION:線性加速度傳感器。
* Sensor.TYPE_AMBIENT_TEMPERATURE:溫度傳感器。
* Sensor.TYPE_LIGHT:光傳感器。
* Sensor.TYPE_PRESSURE:壓力傳感器。
第三步
在onResume()方法中監(jiān)聽(tīng)傳感器傳回的數(shù)據(jù):
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(new SensorEventListener() {
// 當(dāng)傳感器的值改變的時(shí)候回調(diào)該方法
@Override
public void onSensorChanged(SensorEvent event) {
}
// 當(dāng)傳感器精度發(fā)生改變時(shí)回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mSensor, SensorManager.SENSOR_DELAY_GAME);
}1234567891011121314151617
其中,registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs)的三個(gè)參數(shù)說(shuō)明如下:
listener:監(jiān)聽(tīng)傳感器時(shí)間的監(jiān)聽(tīng)器,該監(jiān)聽(tīng)器需要實(shí)現(xiàn)SensorEventListener接口。
sensor:傳感器對(duì)象。
samplingPeriodUs:指定獲取傳感器頻率,一共有如下幾種:
* SensorManager.SENSOR_DELAY_FASTEST:最快,延遲最小,同時(shí)也最消耗資源,一般只有特別依賴傳感器的應(yīng)用使用該頻率,否則不推薦。
* SensorManager.SENSOR_DELAY_GAME:適合游戲的頻率,一般有實(shí)時(shí)性要求的應(yīng)用適合使用這種頻率。
* SensorManager.SENSOR_DELAY_NORMAL:正常頻率,一般對(duì)實(shí)時(shí)性要求不高的應(yīng)用適合使用這種頻率。
* SensorManager.SENSOR_DELAY_UI:適合普通應(yīng)用的頻率,這種模式比較省電,而且系統(tǒng)開(kāi)銷小,但延遲大,因此只適合普通小程序使用。
并在onStop()方法中取消注冊(cè):
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽(tīng)
mSensorManager.unregisterListener(this);
}123456
簡(jiǎn)單3步,就完成了監(jiān)聽(tīng)加速度傳感器的開(kāi)發(fā),是不是so easy?
下面一個(gè)列子,演示了完整的監(jiān)聽(tīng)加速度傳感器的開(kāi)發(fā),并將結(jié)果顯示到屏幕上:
public class MainActivity extends AppCompatActivity implements SensorEventListener{
private SensorManager mSensorManager;
private TextView mTxtValue;
private Sensor mSensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtValue = (TextView) findViewById(R.id.txt_value);
// 獲取傳感器管理對(duì)象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽(tīng)
mSensorManager.unregisterListener(this);
}
// 當(dāng)傳感器的值改變的時(shí)候回調(diào)該方法
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
StringBuilder sb = new StringBuilder();
sb.append(“X方向的加速度:”);
sb.append(values[0]);
sb.append(“\nY方向的加速度:”);
sb.append(values[1]);
sb.append(“\nZ方向的加速度:”);
sb.append(values[2]);
mTxtValue.setText(sb.toString());
}
// 當(dāng)傳感器精度發(fā)生改變時(shí)回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
運(yùn)行結(jié)果:
方向傳感器
方向傳感器用于感應(yīng)手機(jī)的擺放位置,它給我們返回了三個(gè)角度,這三個(gè)角度可以確定手機(jī)的擺放狀態(tài)。
* 第一個(gè)角度:表示手機(jī)頂部朝向與正北方的夾角。當(dāng)手機(jī)繞著Z軸旋轉(zhuǎn)時(shí),該角度值發(fā)生改變。比如,當(dāng)該角度為0度時(shí),表明手機(jī)頂部朝向正北;該角度為90度時(shí),表明手機(jī)頂部朝向正東;該角度為180度時(shí),表明手機(jī)朝向正南;該角度為270度時(shí),表明手機(jī)頂部朝向正西。
* 第二個(gè)角度:表示手機(jī)頂部或尾部翹起的高度。當(dāng)手機(jī)繞著X軸傾斜時(shí),該角度值發(fā)生變化,該角度的取值范圍是-180~180度。假設(shè)手機(jī)屏幕朝上水平放在桌子上,如果桌子是完全水平的,該角度值應(yīng)該是0度。假如從手機(jī)頂部開(kāi)始抬起,直到將手機(jī)沿X軸旋轉(zhuǎn)180度(屏幕向下水平放在桌子上),在這個(gè)旋轉(zhuǎn)的過(guò)程中,該角度值會(huì)從0度變化到-180度。也就是說(shuō),從手機(jī)頂部抬起時(shí),該角度的值會(huì)逐漸減少,直到等于-180度;如果從手機(jī)底部開(kāi)始抬起,直到將手機(jī)沿X軸旋轉(zhuǎn)180度(屏幕向下水平放在桌子上),該角度的值會(huì)從0度變化到180度,也就是說(shuō),從手機(jī)底部抬起時(shí),該角度的值會(huì)逐漸增大,直到等于180度。
* 第三個(gè)角度:表示手機(jī)左側(cè)或右側(cè)翹起的角度。當(dāng)手機(jī)繞著Y軸傾斜時(shí),該角度值發(fā)生改變。該角度的取值范圍是:-90~90度。假設(shè)將手機(jī)屏幕朝上水平放在桌面上,如果桌面是完全水平的,該角度應(yīng)該為0度。如果將手機(jī)從左側(cè)開(kāi)始慢慢抬起,知道將手機(jī)沿著Y軸旋轉(zhuǎn)90度(手機(jī)與桌面垂直),在這個(gè)旋轉(zhuǎn)的過(guò)程中,該角度值會(huì)從0度變化到-90度。也就是說(shuō),從手機(jī)左側(cè)開(kāi)始抬起時(shí),該角度的值會(huì)逐漸的減少,知道等于-90度。如果從手機(jī)的右側(cè)抬起,則剛好相反,會(huì)從0度變化,直到90度。
通過(guò)在應(yīng)用程序中使用方向傳感器,可以實(shí)現(xiàn)如:地圖導(dǎo)航、水平儀、指南針等應(yīng)用。
陀螺儀傳感器
陀螺儀傳感器用于感應(yīng)手機(jī)的旋轉(zhuǎn)速度。陀螺儀傳感器給我們返回了當(dāng)前設(shè)備的X、Y、Z三個(gè)坐標(biāo)軸(坐標(biāo)系統(tǒng)與加速度傳感器一模一樣)的旋轉(zhuǎn)速度。旋轉(zhuǎn)速度的單位是弧度/秒,旋轉(zhuǎn)速度為:
正值代表逆時(shí)針旋轉(zhuǎn),負(fù)值代表順時(shí)針旋轉(zhuǎn)。關(guān)于返回的三個(gè)角速度說(shuō)明如下:
* 第一個(gè)值:代表該設(shè)備繞X軸旋轉(zhuǎn)的角速度。
* 第二個(gè)值:代表該設(shè)備繞Y軸旋轉(zhuǎn)的角速度。
* 第三個(gè)值:代表該設(shè)備繞Z軸旋轉(zhuǎn)的角速度。
磁場(chǎng)傳感器
磁場(chǎng)感應(yīng)器主要讀取設(shè)備周圍的磁場(chǎng)強(qiáng)度。即便是設(shè)備周圍沒(méi)有任何直接的磁場(chǎng),設(shè)備也會(huì)始終處于地球的磁場(chǎng)中,除非你不在地球。。隨著手機(jī)設(shè)備擺放狀態(tài)的改變,周圍磁場(chǎng)在手機(jī)的X、Y、Z方向上的影響也會(huì)發(fā)生改變。磁場(chǎng)傳感器會(huì)返回三個(gè)數(shù)據(jù),分別代表周圍磁場(chǎng)分解到X、Y、Z三個(gè)方向的磁場(chǎng)分量,磁場(chǎng)數(shù)據(jù)的單位是微特斯拉。
重力傳感器
重力傳感器會(huì)返回一個(gè)三維向量,這個(gè)三維向量可顯示重力的方向和強(qiáng)度。重力傳感器的坐標(biāo)系統(tǒng)和加速度傳感器的坐標(biāo)系統(tǒng)相同。
線性加速度傳感器
線性加速度傳感器返回一個(gè)三維向量顯示設(shè)備在各個(gè)方向的加速度(不包含重力加速度)。線性加速度傳感器的坐標(biāo)系統(tǒng)和加速度傳感器的坐標(biāo)系統(tǒng)相同。
線性加速度傳感器、重力傳感器、加速度傳感器,這三者輸出值的關(guān)系如下:
加速度傳感器 = 重力傳感器 + 線性加速度傳感器。
溫度傳感器
溫度傳感器用于獲取設(shè)備所處環(huán)境的溫度。溫度傳感器會(huì)返回一個(gè)數(shù)據(jù),代表手機(jī)設(shè)備周圍的溫度,單位是攝氏度。
光傳感器
光傳感器用于獲取設(shè)備周圍光的強(qiáng)度。光傳感器會(huì)返回一個(gè)數(shù)據(jù),代表手機(jī)周圍光的強(qiáng)度,單位是勒克斯。
壓力傳感器
壓力傳感器用于獲取設(shè)備周圍壓力的大小。壓力傳感器會(huì)返回一個(gè)數(shù)據(jù),代表設(shè)備周圍壓力的大小。
心率傳感器
心率傳感器是在5.0之后新增的一個(gè)傳感器,用于返回佩戴設(shè)備的人每分鐘的心跳次數(shù)。該傳感器返回的數(shù)據(jù)準(zhǔn)確性可以通過(guò)SensorEvent的accuracy進(jìn)行判斷,如果該屬性值為:SENSOR_STATUS_UNRELIABLE或SENSOR_STATUS_NO_CONTACT,則表明傳感器返回的數(shù)據(jù)是不太可靠的,應(yīng)該丟棄。
在使用心率傳感器時(shí),需要增加如下權(quán)限:
《uses-permission android:name=“android.permission.BODY_SENSORS”/》1
實(shí)例(獲取各傳感器數(shù)據(jù)并展示)
public class MainActivity extends AppCompatActivity implements SensorEventListener{
private SensorManager mSensorManager;
private TextView mTxtValue1;
private TextView mTxtValue2;
private TextView mTxtValue3;
private TextView mTxtValue4;
private TextView mTxtValue5;
private TextView mTxtValue6;
private TextView mTxtValue7;
private TextView mTxtValue8;
private TextView mTxtValue9;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtValue1 = (TextView) findViewById(R.id.txt_value1);
mTxtValue2 = (TextView) findViewById(R.id.txt_value2);
mTxtValue3 = (TextView) findViewById(R.id.txt_value3);
mTxtValue4 = (TextView) findViewById(R.id.txt_value4);
mTxtValue5 = (TextView) findViewById(R.id.txt_value5);
mTxtValue6 = (TextView) findViewById(R.id.txt_value6);
mTxtValue7 = (TextView) findViewById(R.id.txt_value7);
mTxtValue8 = (TextView) findViewById(R.id.txt_value8);
mTxtValue9 = (TextView) findViewById(R.id.txt_value9);
// 獲取傳感器管理對(duì)象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
// 為方向傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
// 為陀螺儀傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
// 為磁場(chǎng)傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME);
// 為重力傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);
// 為線性加速度傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_GAME);
// 為溫度傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE), SensorManager.SENSOR_DELAY_GAME);
// 為光傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME);
// 為壓力傳感器注冊(cè)監(jiān)聽(tīng)器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽(tīng)
mSensorManager.unregisterListener(this);
}
// 當(dāng)傳感器的值改變的時(shí)候回調(diào)該方法
@Override
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
// 獲取傳感器類型
int type = event.sensor.getType();
StringBuilder sb;
switch (type){
case Sensor.TYPE_ACCELEROMETER:
sb = new StringBuilder();
sb.append(“加速度傳感器返回?cái)?shù)據(jù):”);
sb.append(“\nX方向的加速度:”);
sb.append(values[0]);
sb.append(“\nY方向的加速度:”);
sb.append(values[1]);
sb.append(“\nZ方向的加速度:”);
sb.append(values[2]);
mTxtValue1.setText(sb.toString());
break;
case Sensor.TYPE_ORIENTATION:
sb = new StringBuilder();
sb.append(“\n方向傳感器返回?cái)?shù)據(jù):”);
sb.append(“\n繞Z軸轉(zhuǎn)過(guò)的角度:”);
sb.append(values[0]);
sb.append(“\n繞X軸轉(zhuǎn)過(guò)的角度:”);
sb.append(values[1]);
sb.append(“\n繞Y軸轉(zhuǎn)過(guò)的角度:”);
sb.append(values[2]);
mTxtValue2.setText(sb.toString());
break;
case Sensor.TYPE_GYROSCOPE:
sb = new StringBuilder();
sb.append(“\n陀螺儀傳感器返回?cái)?shù)據(jù):”);
sb.append(“\n繞X軸旋轉(zhuǎn)的角速度:”);
sb.append(values[0]);
sb.append(“\n繞Y軸旋轉(zhuǎn)的角速度:”);
sb.append(values[1]);
sb.append(“\n繞Z軸旋轉(zhuǎn)的角速度:”);
sb.append(values[2]);
mTxtValue3.setText(sb.toString());
break;
case Sensor.TYPE_MAGNETIC_FIELD:
sb = new StringBuilder();
sb.append(“\n磁場(chǎng)傳感器返回?cái)?shù)據(jù):”);
sb.append(“\nX軸方向上的磁場(chǎng)強(qiáng)度:”);
sb.append(values[0]);
sb.append(“\nY軸方向上的磁場(chǎng)強(qiáng)度:”);
sb.append(values[1]);
sb.append(“\nZ軸方向上的磁場(chǎng)強(qiáng)度:”);
sb.append(values[2]);
mTxtValue4.setText(sb.toString());
break;
case Sensor.TYPE_GRAVITY:
sb = new StringBuilder();
sb.append(“\n重力傳感器返回?cái)?shù)據(jù):”);
sb.append(“\nX軸方向上的重力:”);
sb.append(values[0]);
sb.append(“\nY軸方向上的重力:”);
sb.append(values[1]);
sb.append(“\nZ軸方向上的重力:”);
sb.append(values[2]);
mTxtValue5.setText(sb.toString());
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
sb = new StringBuilder();
sb.append(“\n線性加速度傳感器返回?cái)?shù)據(jù):”);
sb.append(“\nX軸方向上的線性加速度:”);
sb.append(values[0]);
sb.append(“\nY軸方向上的線性加速度:”);
sb.append(values[1]);
sb.append(“\nZ軸方向上的線性加速度:”);
sb.append(values[2]);
mTxtValue6.setText(sb.toString());
break;
case Sensor.TYPE_AMBIENT_TEMPERATURE:
sb = new StringBuilder();
sb.append(“\n溫度傳感器返回?cái)?shù)據(jù):”);
sb.append(“\n當(dāng)前溫度為:”);
sb.append(values[0]);
mTxtValue7.setText(sb.toString());
break;
case Sensor.TYPE_LIGHT:
sb = new StringBuilder();
sb.append(“\n光傳感器返回?cái)?shù)據(jù):”);
sb.append(“\n當(dāng)前光的強(qiáng)度為:”);
sb.append(values[0]);
mTxtValue8.setText(sb.toString());
break;
case Sensor.TYPE_PRESSURE:
sb = new StringBuilder();
sb.append(“\n壓力傳感器返回?cái)?shù)據(jù):”);
sb.append(“\n當(dāng)前壓力為:”);
sb.append(values[0]);
mTxtValue9.setText(sb.toString());
break;
}
}
// 當(dāng)傳感器精度發(fā)生改變時(shí)回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}