Android感測器完全解析
什麼是感測器
維基百科是這樣定義的:感測器是一種物理裝置或生物器官,能夠探測、感受外界的訊號、物理條件(如光、熱、溼度)或化學組成(如煙霧),並將探知的資訊傳遞給其他裝置或器官。
常用感測器介紹與用法
Android平臺支援三個大類的感測器
Motion sensors
(運動感測器)
這些感測器測量加速力,並沿三個軸的旋轉力。此類別包括加速度計,重力感應器, 陀螺儀和旋轉向量感測器。
Environmental sensors
(環境感測器)
這些感測器測量各種環境引數,例如環境空氣溫度和壓力,照明和溼度。此類別包括氣壓計,光度計,和溫度計。
Position sensors
(位置感測器)
這些感測器測量裝置的物理位置。這個類別包括方向感測器和磁力計。
感測器實現流程
第一步:得到SensorManager
SensorManager mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
第二步:註冊感測器
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (null != sensor)
mSensorManager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_NORMAL);
registerListener
這個方法有三個引數。
- 第一個引數是感測器資料變化的監聽器
我們需要去實現SensorEventListener
介面,他裡面有兩個回撥方法,
@Override public void onSensorChanged(SensorEvent event) { //當感測器的數值發生變化時呼叫 }
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //感測器的精度發生變化時呼叫 }
onSensorChanged
方法只有一個SensorEvent
型別的引數event
,其中SensorEvent
類有一個values
變數非常重要,該變數的型別是float[]
。但該變數最多隻有3個元素,而且根據感測器的不同,values
變數中元素所代表的含義也不同。
關於values
值的詳細含義請看參考文章!!!
- 第二個引數是我們需要監聽的感測器
Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor.TYPE_ACCELEROMETER
則是Android
設定感測器型別,這裡是指加速度感測器,
- 第三個引數是感測器資料更新資料的速度
有以下四個值可選,他們的速度是遞增的
SENSOR_DELAY_UI
SENSOR_DELAY_NORMAL
SENSOR_DELAY_GAME
SENSOR_DELAY_FASTEST
感測器的登出
//登出所有感測器物件
public voidunregisterListener(SensorEventListener listener)
//登出指定的感測器物件
public voidunregisterListener(SensorEventListener listener, Sensor sensor)
sensor
的獲取依舊是通過SensorManager.getDefaultSensor()
方法。
獲得手機支援的所有感測器
Listsensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Android感測器型別表
- 加速度感測器:
TYPE_ACCELEROMETER
以m/s2
測量它裝置所有三個物理軸線方向(x,y,和z)加速度。
- 周圍溫度感測器:
TYPE_AMBIENT_TEMPERATURE
檢測周圍空氣溫度。
- 重力感測器:
TYPE_GRAVITY
測量重力
- 陀螺儀感測器:
TYPE_GYROSCOPE
以rad/s測量裝置三個物理軸線方向(x,y,和z)。旋轉速度。
- 光照感測器:
TYPE_LIGHT
以lx測量周圍的光線級別。
- 線性加速度感測器:
TYPE_LINEAR_ACCELERATION
檢測沿著一個軸向的加速度。
- 磁力感測器:
TYPE_MAGNETIC_FIELD
測量周圍的三個物理軸線方向的磁場。
- 方向感測器:
TYPE_ORIENTATION
測量裝置所有三個物理軸線方向(x,y和x)的旋轉角度。
- 壓力感測器:
TYPE_PRESSURE
測量周圍空氣氣壓
- 接近感測器:
TYPE_PROXIMITY
檢測物體與手機的距離
- 相對溼度感測器:
TYPE_RELATIVE_HUMIDITY
檢測周圍空氣相對溼度
- 旋轉向量感測器:
TYPE_ROTATION_VECTOR
用於檢測運動和檢測旋轉。
- 溫度感測器:
TYPE_TEMPERATURE
檢測裝置的溫度
感測器使用實踐
這裡以方向感測器為例
方向感測器的獲取方式
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
上面這個,對,已經被google棄用了,瞭解就好。
Android中的座標系
自己畫的有點醜,將就著看吧,Z
軸預設垂直於地面,所謂獲取的三個Values
陣列即對應手機與Z,Y,X
形成的夾角,後面會說明,
前面說了,TYPE_ORIENTATION
已被棄用,那麼最新的方向感測器是如何做的呢?
事實上,Android 獲取手機旋轉的方向和角度是通過加速度感測器和地磁感測器共同計算得出的
OK,我們這時候是需要同時使用兩個感測器的,看程式碼
Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(listener, accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener, magneticSensor,SensorManager.SENSOR_DELAY_GAME);
同時使用了加速度感測器和地磁感測器
獲取旋轉矩陣陣列R
SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);
獲取手機旋轉資料
SensorManager.getOrientation(R, values);
values
是一個長度為 3 的 float
陣列,手機在各個方向上的旋轉資料都會被存放到這個陣列當中。
對應關係:
values[0]->Z軸、values[1]->X軸、values[2]->Y軸
values[0]
的取值範圍是-180
到180
度,其中±180
度表示正南方向,0
度表示正北方向,-90
度表示正西方向,90
度表示正東方向,如圖
所謂,實踐是檢驗真理的唯一標準,這是我檢測後自行畫的,大家看一下就明白該怎麼根據獲取到的角度來做對應的處理了
一個完整的方向感測器封裝類
public class DirectionSensorUtils implements SensorEventListener {
private SensorManager sensorManager;
float[] accelerometerValues = new float[3];
float[] magneticValues = new float[3];
float lastRotateDegree;
private ImageView compassImg;//指南針背景圖
public DirectionSensorUtils(Context context , ImageView compassImg) {
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
this.compassImg = compassImg;
}
//註冊感測器
public void registerSensor(){
Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.
TYPE_ACCELEROMETER);
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.
TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(this, accelerometerSensor,
SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(this, magneticSensor,
SensorManager.SENSOR_DELAY_GAME);
}
//解除感測器註冊
public void unregisterSensor(){
if (sensorManager != null) {
sensorManager.unregisterListener(this);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
// 判斷當前是加速度感測器還是地磁感測器
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 通過clone()獲取不同的values引用
accelerometerValues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticValues = event.values.clone();
}
//獲取地磁與加速度感測器組合的旋轉矩陣
float[] R = new float[9];
float[] values = new float[3];
SensorManager.getRotationMatrix(R, null, accelerometerValues,
magneticValues);
SensorManager.getOrientation(R, values);
//values[0]->Z軸、values[1]->X軸、values[2]->Y軸
//使用前請進行轉換,因為獲取到的值是弧度,示例如下
// Math.toDegrees(values[0]);
// Math.toDegrees(values[1]);
// Math.toDegrees(values[2]);
handleEvent(values);
}
public void handleEvent(float[] values){
// 這裡實現了一個指南針
float rotateDegree = -(float) Math.toDegrees(values[0]);
if (Math.abs(rotateDegree - lastRotateDegree) > 1) {
RotateAnimation animation = new RotateAnimation
(lastRotateDegree, rotateDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.
RELATIVE_TO_SELF, 0.5f);
animation.setFillAfter(true);
compassImg.startAnimation(animation);
lastRotateDegree = rotateDegree;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
OK,還有其他很多感測器,但使用上大體一致,這裡將光照、加速度、方向感測器封住為了一個工具類,地址:https://github.com/walkthehorizon/UtilsSet/blob/master/UtilsLibrary/SensorUtils.java,如果對你有幫助歡迎fork、star
以及issue
,謝謝
相關文章
- android 感測器Android
- Android 方向感測器Android
- Android View 測量流程(Measure)完全解析AndroidView
- android 中感測器的使用Android
- Android Service完全解析Android
- 感測器-雨滴感測器(雨刷)
- Android ToolBar 使用完全解析Android
- Android DiskLruCache快取完全解析Android快取
- 無線感測器網路與資料交換解析
- Android Fragment 真正的完全解析(上)AndroidFragment
- Android感測器程式設計例項原始碼Android程式設計原始碼
- Android感測器程式設計帶例項(轉)Android程式設計
- 感測器噪聲
- Android中元件生命週期完全解析Android元件
- Android View 佈局流程(Layout)完全解析AndroidView
- Android View 繪製流程(Draw) 完全解析AndroidView
- Android IntentService完全解析 當Service遇到HandlerAndroidIntent
- Android跨程式元件IPCInvoker用法完全解析Android元件
- Android利用感測器實現-仿微信搖一搖Android
- iOS 感測器集錦iOS
- FBG感測器模型模型
- Android ViewDragHelper完全解析 自定義ViewGroup神器AndroidView
- Android Fragment 真正的完全解析(上) (轉載)AndroidFragment
- 深度的Android感測器:近距離和陀螺儀 (有原始碼)Android原始碼
- 樹莓派-感測器篇樹莓派
- Android新特性介紹,ConstraintLayout完全解析AndroidAI
- Android訊息機制不完全解析(上) .Android
- Android訊息機制不完全解析(下) .Android
- win10怎麼關閉感測器_win10禁用感測器功能的方法Win10
- Android原始碼完全解析——View的Measure過程Android原始碼View
- Android 增量更新完全解析 是增量不是熱修復Android
- Android Messenger完全解析 實現程式間通訊AndroidMessenger
- 物聯網如何工作:感測器
- 影像感測器熱點技術
- Arduino 驅動火焰感測器模組UI
- 電磁波類感測器原理
- V – Layout:淘寶、天貓都在用的Android UI框架 完全解析AndroidUI框架
- Android Webp 完全解析 快來縮小apk的大小吧AndroidWebAPK