Android 傳感器開發(fā)詳解
傳感器
傳感器的分類
方向傳感器
陀螺儀傳感器
磁場傳感器
重力傳感器
線性加速度傳感器
溫度傳感器
光傳感器
壓力傳感器
心率傳感器
實例獲取各傳感器數(shù)據(jù)并展示
傳感器的介紹
Android系統(tǒng)提供了對傳感器的支持锣险,如果手機的硬件提供了這些傳感器的話驮宴,那么我們就可以通過代碼獲取手機外部的狀態(tài)岔擂。比如說手機的擺放狀態(tài)、外界的磁場裁替、溫度和壓力等等。
傳感器開發(fā)
對于我們開發(fā)者來說,開發(fā)傳感器十分簡單。只需要注冊監(jiān)聽器锈玉,接收回調(diào)的數(shù)據(jù)就行了,下面來詳細介紹下各傳感器的開發(fā)琉苇。
使用
第一步
// 獲取傳感器管理對象
SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
第二步
// 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
這里我們除了可以獲取加速度傳感器之外嘲玫,還可以獲取其他類型的傳感器,如:
Sensor.TYPE_ORIENTATION:方向傳感器并扇。
Sensor.TYPE_GYROSCOPE:陀螺儀傳感器。
Sensor.TYPE_MAGNETIC_FIELD:磁場傳感器抡诞。
Sensor.TYPE_GRAVITY:重力傳感器穷蛹。
Sensor.TYPE_LINEAR_ACCELERATION:線性加速度傳感器土陪。
Sensor.TYPE_AMBIENT_TEMPERATURE:溫度傳感器。
Sensor.TYPE_LIGHT:光傳感器肴熏。
Sensor.TYPE_PRESSURE:壓力傳感器鬼雀。
第三步
在onResume()方法中監(jiān)聽傳感器傳回的數(shù)據(jù):
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊監(jiān)聽器
mSensorManager.registerListener(new SensorEventListener() {
// 當(dāng)傳感器的值改變的時候回調(diào)該方法
@Override
public void onSensorChanged(SensorEvent event) {
}
// 當(dāng)傳感器精度發(fā)生改變時回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
其中,registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs)的三個參數(shù)說明如下:
listener:監(jiān)聽傳感器時間的監(jiān)聽器蛙吏,該監(jiān)聽器需要實現(xiàn)SensorEventListener接口源哩。
sensor:傳感器對象。
samplingPeriodUs:指定獲取傳感器頻率鸦做,一共有如下幾種:
SensorManager.SENSOR_DELAY_FASTEST:最快励烦,延遲最小,同時也最消耗資源泼诱,一般只有特別依賴傳感器的應(yīng)用使用該頻率坛掠,否則不推薦。
SensorManager.SENSOR_DELAY_GAME:適合游戲的頻率治筒,一般有實時性要求的應(yīng)用適合使用這種頻率屉栓。
SensorManager.SENSOR_DELAY_NORMAL:正常頻率,一般對實時性要求不高的應(yīng)用適合使用這種頻率耸袜。
SensorManager.SENSOR_DELAY_UI:適合普通應(yīng)用的頻率友多,這種模式比較省電,而且系統(tǒng)開銷小堤框,但延遲大夷陋,因此只適合普通小程序使用。
并在onStop()方法中取消注冊:
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽
mSensorManager.unregisterListener(this);
}
簡單3步胰锌,就完成了監(jiān)聽加速度傳感器的開發(fā)骗绕,是不是so easy?
列子
下面一個列子资昧,演示了完整的監(jiān)聽加速度傳感器的開發(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);
// 獲取傳感器管理對象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// 獲取傳感器的類型(TYPE_ACCELEROMETER:加速度傳感器)
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽
mSensorManager.unregisterListener(this);
}
// 當(dāng)傳感器的值改變的時候回調(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ā)生改變時回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
運行結(jié)果:
[圖片上傳失敗...(image-19445-1529942146391)]
方向傳感器(高版本后廢棄)
方向傳感器用于感應(yīng)手機的擺放位置,它給我們返回了三個角度格带,這三個角度可以確定手機的擺放狀態(tài)撤缴。
第一個角度:表示手機頂部朝向與正北方的夾角。當(dāng)手機繞著Z軸旋轉(zhuǎn)時叽唱,該角度值發(fā)生改變屈呕。比如,當(dāng)該角度為0度時棺亭,表明手機頂部朝向正北虎眨;該角度為90度時,表明手機頂部朝向正東;該角度為180度時嗽桩,表明手機朝向正南岳守;該角度為270度時,表明手機頂部朝向正西碌冶。
第二個角度:表示手機頂部或尾部翹起的高度湿痢。當(dāng)手機繞著X軸傾斜時,該角度值發(fā)生變化扑庞,該角度的取值范圍是-180~180度譬重。假設(shè)手機屏幕朝上水平放在桌子上,如果桌子是完全水平的罐氨,該角度值應(yīng)該是0度臀规。假如從手機頂部開始抬起,直到將手機沿X軸旋轉(zhuǎn)180度(屏幕向下水平放在桌子上)岂昭,在這個旋轉(zhuǎn)的過程中以现,該角度值會從0度變化到-180度。也就是說约啊,從手機頂部抬起時邑遏,該角度的值會逐漸減少,直到等于-180度恰矩;如果從手機底部開始抬起记盒,直到將手機沿X軸旋轉(zhuǎn)180度(屏幕向下水平放在桌子上),該角度的值會從0度變化到180度外傅,也就是說纪吮,從手機底部抬起時,該角度的值會逐漸增大萎胰,直到等于180度碾盟。
第三個角度:表示手機左側(cè)或右側(cè)翹起的角度。當(dāng)手機繞著Y軸傾斜時技竟,該角度值發(fā)生改變冰肴。該角度的取值范圍是:-90~90度。假設(shè)將手機屏幕朝上水平放在桌面上榔组,如果桌面是完全水平的熙尉,該角度應(yīng)該為0度。如果將手機從左側(cè)開始慢慢抬起搓扯,知道將手機沿著Y軸旋轉(zhuǎn)90度(手機與桌面垂直)检痰,在這個旋轉(zhuǎn)的過程中,該角度值會從0度變化到-90度锨推。也就是說铅歼,從手機左側(cè)開始抬起時公壤,該角度的值會逐漸的減少,知道等于-90度谭贪。如果從手機的右側(cè)抬起境钟,則剛好相反锦担,會從0度變化俭识,直到90度。
通過在應(yīng)用程序中使用方向傳感器洞渔,可以實現(xiàn)如:地圖導(dǎo)航套媚、水平儀、指南針等應(yīng)用磁椒。
陀螺儀傳感器
陀螺儀傳感器用于感應(yīng)手機的旋轉(zhuǎn)速度堤瘤。陀螺儀傳感器給我們返回了當(dāng)前設(shè)備的X、Y浆熔、Z三個坐標軸(坐標系統(tǒng)與加速度傳感器一模一樣)的旋轉(zhuǎn)速度本辐。旋轉(zhuǎn)速度的單位是弧度/秒,旋轉(zhuǎn)速度為:
正值代表逆時針旋轉(zhuǎn)医增,負值代表順時針旋轉(zhuǎn)慎皱。關(guān)于返回的三個角速度說明如下:
第一個值:代表該設(shè)備繞X軸旋轉(zhuǎn)的角速度。
第二個值:代表該設(shè)備繞Y軸旋轉(zhuǎn)的角速度叶骨。
第三個值:代表該設(shè)備繞Z軸旋轉(zhuǎn)的角速度茫多。
磁場傳感器
磁場感應(yīng)器主要讀取設(shè)備周圍的磁場強度。即便是設(shè)備周圍沒有任何直接的磁場忽刽,設(shè)備也會始終處于地球的磁場中天揖,除非你不在地球。跪帝。隨著手機設(shè)備擺放狀態(tài)的改變今膊,周圍磁場在手機的X、Y伞剑、Z方向上的影響也會發(fā)生改變斑唬。磁場傳感器會返回三個數(shù)據(jù),分別代表周圍磁場分解到X纸泄、Y赖钞、Z三個方向的磁場分量,磁場數(shù)據(jù)的單位是微特斯拉聘裁。
重力傳感器
重力傳感器會返回一個三維向量雪营,這個三維向量可顯示重力的方向和強度。重力傳感器的坐標系統(tǒng)和加速度傳感器的坐標系統(tǒng)相同衡便。
線性加速度傳感器
線性加速度傳感器返回一個三維向量顯示設(shè)備在各個方向的加速度(不包含重力加速度)献起。線性加速度傳感器的坐標系統(tǒng)和加速度傳感器的坐標系統(tǒng)相同洋访。
線性加速度傳感器、重力傳感器谴餐、加速度傳感器姻政,這三者輸出值的關(guān)系如下:
加速度傳感器 = 重力傳感器 + 線性加速度傳感器。
溫度傳感器
溫度傳感器用于獲取設(shè)備所處環(huán)境的溫度岂嗓。溫度傳感器會返回一個數(shù)據(jù)汁展,代表手機設(shè)備周圍的溫度,單位是攝氏度厌殉。
光傳感器
光傳感器用于獲取設(shè)備周圍光的強度食绿。光傳感器會返回一個數(shù)據(jù),代表手機周圍光的強度公罕,單位是勒克斯器紧。
壓力傳感器
壓力傳感器用于獲取設(shè)備周圍壓力的大小。壓力傳感器會返回一個數(shù)據(jù)楼眷,代表設(shè)備周圍壓力的大小铲汪。
心率傳感器
心率傳感器是在5.0之后新增的一個傳感器,用于返回佩戴設(shè)備的人每分鐘的心跳次數(shù)罐柳。該傳感器返回的數(shù)據(jù)準確性可以通過SensorEvent的accuracy進行判斷掌腰,如果該屬性值為:SENSOR_STATUS_UNRELIABLE或SENSOR_STATUS_NO_CONTACT,則表明傳感器返回的數(shù)據(jù)是不太可靠的硝清,應(yīng)該丟棄辅斟。
在使用心率傳感器時,需要增加如下權(quán)限:
<uses-permission android:name="android.permission.BODY_SENSORS"/>
實例(獲取各傳感器數(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);
// 獲取傳感器管理對象
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
// 為加速度傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
// 為方向傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
// 為陀螺儀傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
// 為磁場傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME);
// 為重力傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);
// 為線性加速度傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION), SensorManager.SENSOR_DELAY_GAME);
// 為溫度傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE), SensorManager.SENSOR_DELAY_GAME);
// 為光傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT), SensorManager.SENSOR_DELAY_GAME);
// 為壓力傳感器注冊監(jiān)聽器
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE), SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onStop() {
super.onStop();
// 取消監(jiān)聽
mSensorManager.unregisterListener(this);
}
// 當(dāng)傳感器的值改變的時候回調(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("加速度傳感器返回數(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方向傳感器返回數(shù)據(jù):");
sb.append("\n繞Z軸轉(zhuǎn)過的角度:");
sb.append(values[0]);
sb.append("\n繞X軸轉(zhuǎn)過的角度:");
sb.append(values[1]);
sb.append("\n繞Y軸轉(zhuǎn)過的角度:");
sb.append(values[2]);
mTxtValue2.setText(sb.toString());
break;
case Sensor.TYPE_GYROSCOPE:
sb = new StringBuilder();
sb.append("\n陀螺儀傳感器返回數(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磁場傳感器返回數(shù)據(jù):");
sb.append("\nX軸方向上的磁場強度:");
sb.append(values[0]);
sb.append("\nY軸方向上的磁場強度:");
sb.append(values[1]);
sb.append("\nZ軸方向上的磁場強度:");
sb.append(values[2]);
mTxtValue4.setText(sb.toString());
break;
case Sensor.TYPE_GRAVITY:
sb = new StringBuilder();
sb.append("\n重力傳感器返回數(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線性加速度傳感器返回數(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溫度傳感器返回數(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光傳感器返回數(shù)據(jù):");
sb.append("\n當(dāng)前光的強度為:");
sb.append(values[0]);
mTxtValue8.setText(sb.toString());
break;
case Sensor.TYPE_PRESSURE:
sb = new StringBuilder();
sb.append("\n壓力傳感器返回數(shù)據(jù):");
sb.append("\n當(dāng)前壓力為:");
sb.append(values[0]);
mTxtValue9.setText(sb.toString());
break;
}
}
// 當(dāng)傳感器精度發(fā)生改變時回調(diào)該方法
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
運行結(jié)果:
[圖片上傳失敗...(image-564491-1529942146390)]
https://blog.csdn.net/airsaid/article/details/52902299
+??YU???!