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