Android Sensor 傳感器總結(jié)

refs: https://developer.android.google.cn/guide/topics/sensors/

Android Sensor Framework 概覽

關(guān)于Android 傳感器坐標(biāo)與讀數(shù)的進(jìn)一步討論

1. 傳感器分類

Android平臺支持三個(gè)大類的傳感器

  • Motion sensors(運(yùn)動傳感器)
    這些傳感器測量加速力脆诉,并沿三個(gè)軸的旋轉(zhuǎn)力十绑。此類別包括加速度計(jì),重力感應(yīng)器, 陀螺儀和旋轉(zhuǎn)矢量傳感器来屠。
  • Environmental sensors (環(huán)境傳感器)
    這些傳感器測量各種環(huán)境參數(shù),例如環(huán)境空氣溫度和壓力,照明和濕度。此類別包括氣壓計(jì)躲舌,光度計(jì),和溫度計(jì)性雄。
  • Position sensors (位置傳感器)
    這些傳感器測量設(shè)備的物理位置没卸。這個(gè)類別包括方向傳感器和磁力計(jì)。

目前 Android 平臺支持的傳感器type如下:

Sensor Type Description Common Uses
TYPE_ACCELEROMETER Hardware Measures the acceleration force in m/s2 that is applied to a device on all three physical axes (x, y, and z), including the force of gravity. Motion detection (shake, tilt, etc.).
TYPE_AMBIENT_TEMPERATURE Hardware Measures the ambient room temperature in degrees Celsius (°C). See note below. Monitoring air temperatures.
TYPE_GRAVITY Software or Hardware Measures the force of gravity in m/s2 that is applied to a device on all three physical axes (x, y, z). Motion detection (shake, tilt, etc.).
TYPE_GYROSCOPE Hardware Measures a device's rate of rotation in rad/s around each of the three physical axes (x, y, and z). Rotation detection (spin, turn, etc.).
TYPE_LIGHT Hardware Measures the ambient light level (illumination) in lx. Controlling screen brightness.
TYPE_LINEAR_ACCELERATION Software or Hardware Measures the acceleration force in m/s2 that is applied to a device on all three physical axes (x, y, and z), excluding the force of gravity. Monitoring acceleration along a single axis.
TYPE_MAGNETIC_FIELD Hardware Measures the ambient geomagnetic field for all three physical axes (x, y, z) in μT. Creating a compass.
TYPE_ORIENTATION Software Measures degrees of rotation that a device makes around all three physical axes (x, y, z). As of API level 3 you can obtain the inclination matrix and rotation matrix for a device by using the gravity sensor and the geomagnetic field sensor in conjunction with the getRotationMatrix() method. Determining device position.
TYPE_PRESSURE Hardware Measures the ambient air pressure in hPa or mbar. Monitoring air pressure changes.
TYPE_PROXIMITY Hardware Measures the proximity of an object in cm relative to the view screen of a device. This sensor is typically used to determine whether a handset is being held up to a person's ear. Phone position during a call.
TYPE_RELATIVE_HUMIDITY Hardware Measures the relative ambient humidity in percent (%). Monitoring dewpoint, absolute, and relative humidity.
TYPE_ROTATION_VECTOR Software or Hardware Measures the orientation of a device by providing the three elements of the device's rotation vector. Motion detection and rotation detection.
TYPE_TEMPERATURE Hardware Measures the temperature of the device in degrees Celsius (°C). This sensor implementation varies across devices and this sensor was replaced with the TYPE_AMBIENT_TEMPERATURE sensor in API Level 14 Monitoring temperatures.

2. 常規(guī)使用流程

2.1 常用api

SensorManager:可以通過這個(gè)類去創(chuàng)建一個(gè)傳感器服務(wù)的實(shí)例毅贮,這個(gè)類提供的各種方法可以訪問傳感器列表办悟、注冊或解除注冊傳感器事件監(jiān)聽、獲取方位信息等滩褥。

Sensor:用于創(chuàng)建一個(gè)特定的傳感器實(shí)例,這個(gè)類提供的方法可以讓你決定一個(gè)傳感器的功能炫加。

SensorEvent:系統(tǒng)會通過這個(gè)類創(chuàng)建一個(gè)傳感器事件對象瑰煎,提供了一個(gè)傳感器的事件信息,包含一下內(nèi)容俗孝,原生的傳感器數(shù)據(jù)酒甸、觸發(fā)傳感器的事件類型、精確的數(shù)據(jù)以及事件發(fā)生的時(shí)間赋铝。

SensorEventListener:可以通過這個(gè)接口創(chuàng)建兩個(gè)回調(diào)用法來接收傳感器的事件通知插勤,比如當(dāng)傳感器的值發(fā)生變化時(shí)。

2.2 使用方式

第一步:獲取SensorManager對象

第二步:獲取Sensor對象

第三步:注冊Sensor對象

第四步:重寫onAccuracyChanged,onSensorChanged這兩個(gè)方法

第五步:注銷Sensor對象

public class SensorActivity extends Activity implements SensorEventListener {
  private SensorManager mSensorManager;
  private Sensor mSensor;
  @Override
  public final void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //第一步:通過getSystemService獲得SensorManager實(shí)例對象
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    //第二步:通過SensorManager實(shí)例對象獲得想要的傳感器對象:參數(shù)決定獲取哪個(gè)傳感器
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
  }
  //第四步:必須重寫的兩個(gè)方法:onAccuracyChanged农尖,onSensorChanged
  /**
   * 傳感器精度發(fā)生改變的回調(diào)接口
   */
  @Override
  public final void onAccuracyChanged(Sensor sensor, int accuracy) {
    //TODO 在傳感器精度發(fā)生改變時(shí)做些操作析恋,accuracy為當(dāng)前傳感器精度
  }
  /**
   * 傳感器事件值改變時(shí)的回調(diào)接口:執(zhí)行此方法的頻率與注冊傳感器時(shí)的頻率有關(guān)
   */
  @Override
  public final void onSensorChanged(SensorEvent event) {
    // 大部分傳感器會返回三個(gè)軸方向x,y,x的event值,值的意義因傳感器而異
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];
    //TODO 利用獲得的三個(gè)float傳感器值做些操作
  }
  /**
   * 第三步:在獲得焦點(diǎn)時(shí)注冊傳感器并讓本類實(shí)現(xiàn)SensorEventListener接口
   */
  @Override
  protected void onResume() {
    super.onResume();
    /*
     *第一個(gè)參數(shù):SensorEventListener接口的實(shí)例對象
     *第二個(gè)參數(shù):需要注冊的傳感器實(shí)例
     *第三個(gè)參數(shù):傳感器獲取傳感器事件event值頻率:
   *              SensorManager.SENSOR_DELAY_FASTEST = 0:對應(yīng)0微秒的更新間隔盛卡,最快助隧,1微秒 = 1 % 1000000秒
   *              SensorManager.SENSOR_DELAY_GAME = 1:對應(yīng)20000微秒的更新間隔,游戲中常用
   *              SensorManager.SENSOR_DELAY_UI = 2:對應(yīng)60000微秒的更新間隔
   *              SensorManager.SENSOR_DELAY_NORMAL = 3:對應(yīng)200000微秒的更新間隔
   *              鍵入自定義的int值x時(shí):對應(yīng)x微秒的更新間隔
     *
     */
    mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
  }
  /**
   * 第五步:在失去焦點(diǎn)時(shí)注銷傳感器
   */
  @Override
  protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
  }
}

注意滑沧,設(shè)備不一定支持你需要的sensor并村,使用前可以先判斷下可用性

private SensorManager mSensorManager;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

//或者
List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);

3. 常用Sensor的解釋

Accelerometer 加速度傳感器

加速度傳感器又叫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軸為正值患膛。

Magnetometer 磁力傳感器

磁力傳感器簡稱為M-sensor摊阀,返回x、y踪蹬、z三軸的環(huán)境磁場數(shù)據(jù)胞此。

該數(shù)值的單位是微特斯拉(micro-Tesla),用uT表示跃捣。 單位也可以是高斯(Gauss)漱牵,1Tesla=10000Gauss。 硬件上一般沒有獨(dú)立的磁力傳感器疚漆,磁力數(shù)據(jù)由電子羅盤傳感器提供(E-compass)酣胀。

電子羅盤傳感器同時(shí)提供下文的方向傳感器數(shù)據(jù)刁赦。

Orientation 方向傳感器

方向傳感器簡稱為O-sensor,返回三軸的角度數(shù)據(jù)闻镶,方向數(shù)據(jù)的單位是角度甚脉。

為了得到精確的角度數(shù)據(jù),E-compass(電子羅盤傳感器)需要獲取G-sensor(加速度傳感器)的數(shù)據(jù)儒溉, 經(jīng)過計(jì)算生產(chǎn)O-sensor數(shù)據(jù)宦焦,否則只能獲取水平方向的角度。

方向傳感器提供三個(gè)數(shù)據(jù)顿涣,分別為azimuth波闹、pitch和roll。

azimuth:方位涛碑,返回水平時(shí)磁北極和Y軸的夾角精堕,范圍為0°至360°。 0°=北蒲障,90°=東歹篓,180°=南,270°=西揉阎。

pitch:x軸和水平面的夾角庄撮,范圍為-180°至180°。 當(dāng)z軸向y軸轉(zhuǎn)動時(shí)毙籽,角度為正值洞斯。

roll:y軸和水平面的夾角,由于歷史原因坑赡,范圍為-90°至90°烙如。 當(dāng)x軸向z軸移動時(shí),角度為正值毅否。

電子羅盤在獲取正確的數(shù)據(jù)前需要進(jìn)行校準(zhǔn)亚铁,通常可用8字校準(zhǔn)法螟加。 8字校準(zhǔn)法要求用戶使用需要校準(zhǔn)的設(shè)備在空中做8字晃動徘溢, 原則上盡量多的讓設(shè)備法線方向指向空間的所有8個(gè)象限。

Gyroscope 陀螺儀傳感器

陀螺儀傳感器叫做Gyro-sensor捆探,返回x甸昏、y、z三軸的角速度數(shù)據(jù)徐许。

角速度的單位是radians/second。

根據(jù)Nexus S手機(jī)實(shí)測: 水平逆時(shí)針旋轉(zhuǎn)卒蘸,Z軸為正雌隅。 水平逆時(shí)針旋轉(zhuǎn)翻默,z軸為負(fù)。 向左旋轉(zhuǎn)恰起,y軸為負(fù)修械。 向右旋轉(zhuǎn),y軸為正检盼。 向上旋轉(zhuǎn)肯污,x軸為負(fù)。 向下旋轉(zhuǎn)吨枉,x軸為正蹦渣。

Ambient Light Sensor (環(huán)境)光線感應(yīng)傳感器

光線感應(yīng)傳感器檢測實(shí)時(shí)的光線強(qiáng)度,光強(qiáng)單位是lux(勒克司度)貌亭,其物理意義是照射到單位面積上的光通量柬唯。

光線感應(yīng)傳感器主要用于Android系統(tǒng)的LCD自動亮度功能。

可以根據(jù)采樣到的光強(qiáng)數(shù)值實(shí)時(shí)調(diào)整LCD的亮度圃庭。

Barometer Sensor (氣)壓力傳感器

壓力傳感器返回當(dāng)前的壓強(qiáng)锄奢,單位是百帕斯卡hectopascal(hPa)。

Temperature Sensor 溫度傳感器

溫度傳感器返回當(dāng)前的溫度剧腻。

Proximity Sensor (近)距離傳感器

又稱接近傳感器拘央,檢測物體與手機(jī)的距離,單位是cm(厘米)书在。

一些接近傳感器只能返回遠(yuǎn)和近兩個(gè)狀態(tài)灰伟, 因此,接近傳感器將最大距離返回遠(yuǎn)狀態(tài)蕊温,小于最大距離返回近狀態(tài)袱箱。 接近傳感器可用于接聽電話時(shí)自動關(guān)閉LCD屏幕以節(jié)省電量。

一些芯片集成了接近傳感器和光線傳感器兩者功能义矛。

Gravity 重力傳感器

重力傳感器簡稱GV-sensor发笔,輸出重力數(shù)據(jù)。

在地球上凉翻,重力數(shù)值為9.8了讨,單位是m/s^2。 坐標(biāo)系統(tǒng)與加速度傳感器相同制轰。 當(dāng)設(shè)備復(fù)位時(shí)前计,重力傳感器的輸出與加速度傳感器相同。

Linear Acceleration 線性加速度傳感器

線性加速度傳感器簡稱LA-sensor垃杖。

線性加速度傳感器是加速度傳感器減去重力影響獲取的數(shù)據(jù)男杈。 單位是m/s^2,坐標(biāo)系統(tǒng)與加速度傳感器相同调俘。

加速度傳感器伶棒、重力傳感器和線性加速度傳感器的計(jì)算公式如下: 加速度 = 重力 + 線性加速度

Rotation Vector 旋轉(zhuǎn)矢量傳感器

旋轉(zhuǎn)矢量傳感器簡稱RV-sensor旺垒。

旋轉(zhuǎn)矢量代表設(shè)備的方向,是一個(gè)將坐標(biāo)軸和角度混合計(jì)算得到的數(shù)據(jù)肤无。

RV-sensor輸出三個(gè)數(shù)據(jù): xsin(theta/2) ysin(theta/2) z*sin(theta/2) sin(theta/2)是RV的數(shù)量級先蒋。

RV的方向與軸旋轉(zhuǎn)的方向相同。 RV的三個(gè)數(shù)值宛渐,與cos(theta/2)組成一個(gè)四元組竞漾。 RV的數(shù)據(jù)沒有單位,使用的坐標(biāo)系與加速度相同窥翩。

舉例:

sensors_event_t.data[0] = x*sin(theta/2)

sensors_event_t.data[1] = ysin(theta/2)

sensors_event_t.data[2] = z*sin(theta/2)

sensors_event_t.data[3] = cos(theta/2)

其他傳感器

Step Detector 步數(shù)探測器
Step Counter 計(jì)步器
Significant Motion Detector 運(yùn)動檢測器
Game Rotation Vector 游戲旋轉(zhuǎn)矢量
Geomagnetic Rotation Vector 地磁旋轉(zhuǎn)矢量
Basic Gestures 基本手勢
Motion Accel 運(yùn)動加速度

4. 坐標(biāo)系統(tǒng)

手機(jī)的自然坐標(biāo)系

當(dāng)一個(gè)設(shè)備被放在其默認(rèn)的方向上時(shí)业岁,X軸是水平指向右的,Y軸是垂直向上的鳍烁,Z軸是指向屏幕正面之外的叨襟,即屏幕背面是Z的負(fù)值。

img

當(dāng)設(shè)備運(yùn)動或者旋轉(zhuǎn)的時(shí)候幔荒,這些坐標(biāo)軸是不會改變的糊闽,即它們是跟隨手機(jī)的。

即是說爹梁,手機(jī)坐標(biāo)系是跟隨設(shè)備的自然方向的(但是請記住自然方向不一定是豎直右犹,比如平板它的自然方向就很有可能是橫向)。

使用這個(gè)坐標(biāo)系的傳感器:

即是說它們的度數(shù)顯示了在手機(jī)的這三個(gè)軸上的數(shù)字大小姚垃。

屏幕旋轉(zhuǎn)

常常要考慮屏幕的旋轉(zhuǎn)念链,即屏幕畫面相對于自然方向的旋轉(zhuǎn)。

于是就需要使用 getRotation()方法來獲取屏幕的旋轉(zhuǎn)值积糯。

這個(gè)方法是Display類中的掂墓,跟傳感器不相關(guān)。

這個(gè)方法的返回值只對應(yīng)0看成,90,180,270四種旋轉(zhuǎn)情況君编,它說明屏幕顯示區(qū)域的旋轉(zhuǎn)情況。

世界坐標(biāo)系

有一些傳感器和方法使用相對于世界的坐標(biāo)系川慌,因?yàn)樗鼈兎祷氐臄?shù)據(jù)反映設(shè)備相對于地球及真實(shí)環(huán)境的位置信息吃嘿。

請見getOrientation() 方法,getRotationMatrix() 方法梦重,Orientation Sensor, 和 Rotation Vector Sensor兑燥。

getRotationMatrix()

getRotationMatrix()方法說明中,定義的世界坐標(biāo)系如下:

?
img

X軸平行于地面琴拧,指向東方降瞳。

Y軸平行于地面,指向北極方向蚓胸。

Z軸垂直于地面力崇,指向天空斗塘。

getOrientation()

getOrientation() 方法中所用的坐標(biāo)系與上面的不同:

?
img

X軸平行于地面,指向西方亮靴;

Y軸平行于地面,指向地磁場北極于置。

Z軸垂直于地面茧吊,指向地心。

getOrientation方法的返回值表示:

values[0]: azimuth, rotation around the Z axis.

values[1]: pitch, rotation around the X axis.

values[2]: roll, rotation around the Y axis.

并且這三個(gè)角度值都是以弧度做單位八毯,逆時(shí)針方向?yàn)檎?/p>

方向傳感器的返回值說明

方向傳感器是利用加速度計(jì)和地磁場傳感器得到自己的數(shù)據(jù)搓侄。

方向傳感器比較特殊,因?yàn)樗臄?shù)值是相對于絕對方向的话速。它得到的是手機(jī)設(shè)備的絕對姿態(tài)值讶踪。

一個(gè)方向傳感器得到的三維數(shù)據(jù)如下:

(參見http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-orient

方向傳感器返回的都是角度值,以度數(shù)為單位泊交。

注意下面說的x乳讥、y、z軸均是手機(jī)自身的坐標(biāo)軸廓俭。

第一個(gè)角度:Azimuth (degrees of rotation around the z axis).

表示手機(jī)自身的y軸與地磁場北極方向的角度云石,即手機(jī)頂部朝向與正北方向的角度。

(This is the angle between magnetic north and the device's y axis. )

當(dāng)手機(jī)繞著自身的z軸旋轉(zhuǎn)時(shí)法严,該角度值將發(fā)生改變痊土。

例如該角度值為0時(shí)挽封,表示手機(jī)頂部指向正北;該角度為90度時(shí)宽菜,代表手機(jī)頂部指向正東;該角度為180度時(shí)竿报,代表手機(jī)頂部指向正南铅乡;該角度為270度時(shí),代表手機(jī)頂部指向正西仰楚。

第二個(gè)角度:Pitch (degrees of rotation around the x axis).

表示手機(jī)頂部或尾部翹起的角度隆判。

當(dāng)手機(jī)繞著自身的x軸旋轉(zhuǎn),該角度會發(fā)生變化僧界,值的范圍是-180到180度侨嘀。

當(dāng)z軸正向朝著y軸正向旋轉(zhuǎn)時(shí),該角度是正值捂襟;當(dāng)z軸正向朝著y軸負(fù)向旋轉(zhuǎn)時(shí)咬腕,該角度是負(fù)值。

假設(shè)將手機(jī)屏幕朝上水平放在桌子上葬荷,如果桌子是完全水平的涨共,該角度應(yīng)該是0纽帖。

假如從手機(jī)頂部抬起,直到將手機(jī)沿x軸旋轉(zhuǎn)180度(屏幕向下水平放在桌面上)举反,這個(gè)過程中懊直,該角度值會從0變化到-180。

如果從手機(jī)底部開始抬起火鼻,直到將手機(jī)沿x軸旋轉(zhuǎn)180度(屏幕向下水平放在桌面上)室囊,該角度的值會從0變化到180。

第三個(gè)角度:Roll (degrees of rotation around the y axis).

表示手機(jī)左側(cè)或右側(cè)翹起的角度魁索。

當(dāng)手機(jī)繞著自身x軸旋轉(zhuǎn)時(shí)融撞,該角度值將會發(fā)生變化,取值范圍是-90到90度粗蔚。

當(dāng)z軸正向朝著x軸正向旋轉(zhuǎn)時(shí)尝偎,該角度是負(fù)值;

當(dāng)z軸正向朝著x軸負(fù)向旋轉(zhuǎn)時(shí)鹏控,該角度是正值致扯。\

(這里跟官方文檔的說法有點(diǎn)不太一致,即第三個(gè)角度的正負(fù)號正好相反牧挣,我不知道是文檔寫錯(cuò)了急前,還是它用了別的什么坐標(biāo)系)。

因?yàn)橥ㄟ^真機(jī)測試瀑构,結(jié)果如下:

將手機(jī)屏幕朝上水平放在桌子上裆针,如果桌子是完全水平的,該角度應(yīng)該是0寺晌。

假如將手機(jī)左側(cè)逐漸抬起世吨,直到將手機(jī)沿Y軸旋轉(zhuǎn)90度(手機(jī)與桌面垂直),在這個(gè)旋轉(zhuǎn)過程中呻征,該角度會從0變化到-90耘婚。

如果從手機(jī)的右側(cè)開始抬起,直到將手機(jī)沿Y軸旋轉(zhuǎn)90度(手機(jī)與桌面垂直)陆赋,該角度的值會從0變化到90度沐祷。

其他說明:

由于需要計(jì)算,所以方向傳感器的準(zhǔn)確度和精度都會受到影響攒岛。

官方文檔上說赖临,只有當(dāng)?shù)谌齻€(gè)roll的角度值為0的時(shí)候得到的值比較可靠。

specifically, this sensor is only reliable when the roll component is 0灾锯。

所以從Android 2.2 (API level 8)開始兢榨,不建議使用方向傳感器。

建議使用 getRotationMatrix()getOrientation() 結(jié)合來計(jì)算方向值。

也可以利用 remapCoordinateSystem()方法來進(jìn)行一些方向值向其他坐標(biāo)系的轉(zhuǎn)換吵聪。

5. 運(yùn)動傳感器 Motion Sensors

Android平臺提供了一些監(jiān)控設(shè)備運(yùn)動的傳感器凌那。

運(yùn)動傳感器中有兩個(gè)永遠(yuǎn)是基于硬件的,即加速度計(jì)陀螺儀accelerometer and gyroscope)吟逝。

運(yùn)動傳感器中有三個(gè)是既可以基于硬件又可以基于軟件的帽蝶,即重力感應(yīng)器、線性加速度計(jì)澎办、旋轉(zhuǎn)向量傳感器嘲碱。

運(yùn)動傳感器用來監(jiān)測設(shè)備的運(yùn)動,比如傾斜局蚀,震動,旋轉(zhuǎn)或搖擺(tilt, shake, rotation, or swing)恕稠。

運(yùn)動傳感器的返回值

所有的運(yùn)動傳感器都返回一個(gè)多維的向量值琅绅,保存在SensorEventvalues數(shù)組中。

參見鏈接:https://developer.android.google.cn/guide/topics/sensors/sensors_motion

image.png

加速度計(jì)Accelerometer

加速度傳感器測量作用于設(shè)備的加速度Ad:

Ad = -∑Fs / mass

公式中是施加于設(shè)備的外力之和和設(shè)備質(zhì)量的比值鹅巍。

但是千扶,重力加速度會影響這個(gè)公式:

Ad = -g -∑F / mass

我的理解是:Ad是設(shè)備的實(shí)際加速度(我們想知道的值),而加速度的讀數(shù)是一個(gè)受到了重力影響的讀數(shù)骆捧。即Ad+9.81澎羞;

比如,把設(shè)備靜止地平放在桌面上敛苇,這時(shí)妆绞,Ad是零;加速度計(jì)的讀數(shù)大小是重力加速度的數(shù)值g = 9.81 m/s2枫攀。這個(gè)常量值的大小可以用STANDARD_GRAVITY來表示括饶。

而當(dāng)設(shè)備自由落體時(shí),它以9.81 m/s2的加速度向地面運(yùn)動来涨,Ad為-9.81 m/s2图焰,這時(shí)加速度計(jì)的讀數(shù)應(yīng)該是0。

坐標(biāo)系的設(shè)置

當(dāng)把設(shè)備平放在桌面上蹦掐,以它的自然方向放置:

如果你從設(shè)備左邊推它技羔,它往右移,這時(shí)它的X加速度值是正的卧抗;

如果你從設(shè)備下方推它藤滥,它將朝著遠(yuǎn)離你的方向移動,這時(shí)它的Y加速度值是正的颗味;

如果你把設(shè)備以A m/s2的加速度推向天空超陆,Z軸的加速度值應(yīng)當(dāng)?shù)扔贏 + 9.81,(which corresponds to the acceleration of the device (+A m/s2) minus the force of gravity (-9.81 m/s2))。

重力傳感器Gravity Sensor

重力傳感器測量的是重力值在三個(gè)方向上的大小时呀。

重力傳感器和加速度傳感器的單位一樣m/s2张漂,并且它們使用的坐標(biāo)系也一樣。

當(dāng)設(shè)備靜止時(shí)谨娜,重力傳感器的輸出和加速度傳感器的輸出是完全一致的航攒。

陀螺儀Gyroscope

陀螺儀測量的是設(shè)備繞三個(gè)軸向的旋轉(zhuǎn)速度,單位是rad/s趴梢。

所使用的坐標(biāo)系統(tǒng)仍然和加速度計(jì)的一樣漠畜。

旋轉(zhuǎn)的值在逆時(shí)針方向?yàn)檎次氚校绻粋€(gè)觀察者從某個(gè)軸的正向某點(diǎn)向原點(diǎn)看憔狞,如果觀察到的旋轉(zhuǎn)是逆時(shí)針的,則是一個(gè)正值的旋轉(zhuǎn)彰阴。這是一個(gè)關(guān)于旋轉(zhuǎn)方向的標(biāo)準(zhǔn)的數(shù)學(xué)定義瘾敢,注意,這個(gè)和方向傳感器所用的定義不同尿这。

陀螺儀的輸出需要對時(shí)間積分來計(jì)算簇抵。有一個(gè)例子見:http://developer.android.com/guide/topics/sensors/sensors_motion.html

標(biāo)準(zhǔn)的陀螺儀提供原始的旋轉(zhuǎn)數(shù)據(jù),對噪聲和漂移沒有過濾和校正射众。

實(shí)際運(yùn)用時(shí)碟摆,陀螺儀的噪聲和漂移會引入錯(cuò)誤,所以需要被補(bǔ)償叨橱。通车渫桑可以通過其他傳感器(重力傳感器或加速度計(jì))來檢測噪聲和漂移。

線性加速度計(jì)Linear Accelerometer

線性加速度計(jì)提供了沿著每個(gè)軸的加速度值雏逾,并且是排除了重力的值嘉裤。

即:linear acceleration = acceleration - acceleration due to gravity

它所使用的單位和坐標(biāo)系都和加速度計(jì)相同。

線性加速度計(jì)有一個(gè)偏移值(offset)栖博,你需要移除這個(gè)偏移值屑宠,比較簡單的方法是在你的應(yīng)用一開始設(shè)置一個(gè)標(biāo)定步驟:讓用戶把設(shè)備放在桌子上,然后讀出三個(gè)軸的offset值仇让,之后典奉,在從線性加速度計(jì)中讀數(shù)的時(shí)候減去這個(gè)offset值,就可以得到實(shí)際的線性加速度值丧叽。

旋轉(zhuǎn)向量傳感器Rotation Vector Sensor

旋轉(zhuǎn)向量用一個(gè)角度和軸向的組合來表達(dá)設(shè)備的方向信息卫玖。比如,設(shè)備繞著某一個(gè)軸向旋轉(zhuǎn)了一個(gè)角度 θ踊淳。

旋轉(zhuǎn)向量的三個(gè)元素的值如下:

x*sin(θ/2)

y*sin(θ/2)

z*sin(θ/2)

rotation vector的大小是sin(θ/2)假瞬,方向是它的旋轉(zhuǎn)軸向陕靠。

旋轉(zhuǎn)向量沒有單位。

X軸指向東脱茉,Y軸指向北剪芥,Z軸與地面垂直,指向天空琴许。

6. 位置傳感器Position Sensors

Android平臺提供了兩種決定設(shè)備位置的傳感器:

地磁場傳感器方向傳感器(the geomagnetic field sensor and the orientation sensor)税肪。

還有一種傳感器用于檢測設(shè)備正面和其他物體的距離,叫做接近傳感器(proximity sensor)榜田。

地磁場傳感器和接近傳感器是基于硬件的益兄。

方向傳感器是基于軟件的,它的數(shù)據(jù)是根據(jù)加速度計(jì)和地磁場傳感器導(dǎo)出的箭券。

但是方向傳感器自從Android 2.2 (API Level 8)開始就被廢棄了净捅。

位置傳感器也是返回一個(gè)多維向量,放在 SensorEvent中的values數(shù)組中辩块。

返回值見表:

img

方向傳感器Orientation Sensor

方向傳感器是根據(jù)地磁場傳感器加速度計(jì)推導(dǎo)出輸出數(shù)據(jù)的灸叼。

使用這兩個(gè)硬件傳感器,方向傳感器為下面三個(gè)方向提供了數(shù)據(jù):

1. Azimuth:繞Z軸旋轉(zhuǎn)的度數(shù)庆捺。這是設(shè)備的y軸和地磁場北極的夾角。比如屁魏,設(shè)備的y軸指向東滔以,這個(gè)度數(shù)就為90。

2. Pitch:繞X軸旋轉(zhuǎn)的度數(shù)氓拼。當(dāng)設(shè)備的z軸朝著y軸正向旋轉(zhuǎn)時(shí)你画,這個(gè)值是正值,反之桃漾,當(dāng)設(shè)備的z軸朝著y軸的負(fù)向旋轉(zhuǎn)時(shí)坏匪,這個(gè)值為負(fù)值。它的取值范圍是-180到180撬统。

3. Roll:繞Y軸旋轉(zhuǎn)的度數(shù)适滓。當(dāng)設(shè)備的z軸朝著x軸正向旋轉(zhuǎn)時(shí),這個(gè)值是正值恋追,反之凭迹,當(dāng)設(shè)備的z軸朝著x軸的負(fù)向旋轉(zhuǎn)時(shí),這個(gè)值為負(fù)值苦囱。它的取值范圍是-90到90嗅绸。

注意這個(gè)定義是非常特殊的,因?yàn)樗陧槙r(shí)針旋轉(zhuǎn)的時(shí)候是正值撕彤,而數(shù)學(xué)上總是逆時(shí)針為正值鱼鸠。

因?yàn)榉较騻鞲衅餍枰罅康奶幚磉\(yùn)算,所以它的準(zhǔn)確度和精度都有所下降。后來蚀狰,自Android 2.2 (API level 8)愉昆,方向傳感器被廢棄。自Android 4.4W (API level 20)造锅,方向傳感器類型被廢棄撼唾。

官方建議使用下面的方法:

利用getRotationMatrix()結(jié)合getOrientation()方法可以計(jì)算方向值。

https://developer.android.google.cn/guide/topics/sensors/sensors_position#sensors-pos-orient

還可以利用remapCoordinateSystem()把方向值轉(zhuǎn)換到你的應(yīng)用的參考坐標(biāo)系哥蔚。

地磁場傳感器Geomagnetic Field Sensor

地磁場傳感器監(jiān)測地球地磁場變化倒谷。

傳感器提供三個(gè)坐標(biāo)上的原始的磁場強(qiáng)度值(in μT)。

一般情況下糙箍,你不需要直接使用這個(gè)傳感器渤愁,你可以使用旋轉(zhuǎn)向量傳感器來決定原始的旋轉(zhuǎn)運(yùn)動;你也可以使用加速度計(jì)和地磁場傳感器并結(jié)合getRotationMatrix()方法來獲得旋轉(zhuǎn)矩陣和傾斜矩陣深夯。

你可以結(jié)合 getOrientation()getInclination() 方法來使用這些矩陣抖格,從而得到方位和地磁場偏移數(shù)據(jù)。

接近傳感器Proximity Sensor

接近傳感器可以讓你得到設(shè)備離另一個(gè)物體的距離咕晋。

接近傳感器通常用于檢測設(shè)備正面和用戶頭部的距離雹拄,比如用戶正在打電話。

大多數(shù)Proximity Sensor返回絕對的距離數(shù)值掌呜,以cm為單位滓玖。但是也有一些只返回近或者遠(yuǎn)。

7. Android Sensor Framework 概覽

7.1 Overview

Android Sensor Framework 的整體架構(gòu)如圖所示:

Android Sensor Framework 可以分為 3 大部分质蕉,各個(gè)部分的主要功能如下:

SDK
這一部分主要功能是為 Application 提供 Java API 接口势篡,以便 Application 可以開啟所需的 Sensor 并獲取數(shù)據(jù)。

Framework
這一部分主要有 Sensor Service 構(gòu)成模暗,主要實(shí)現(xiàn)了 Sensor 數(shù)據(jù)流和控制流禁悠。

Libraries
這一部分是 Sensor 的硬件抽象層(HAL),它實(shí)現(xiàn)了 Sensor 的具體操作和數(shù)據(jù)獲取功能兑宇。同時(shí)碍侦,它還進(jìn)行虛擬 Sensor,電子羅盤等相關(guān)的算法處理過程顾孽。此模塊通常以一個(gè)動態(tài)鏈接庫的形式提供祝钢。

7.2 Android Sensor Framework 類圖

圖片 2

7.3 Android Sensor SDK

上圖中的 Client 部分內(nèi)容即為 Android Sensor SDK 的主要構(gòu)成。主要類的主要功能如下:

SensorManager
該類主要封裝了 Sensor 相關(guān)的 API 若厚,提供給 Application 使用拦英。
文件路徑:frameworks/base/core/java/android/hardware/SensorManager.java

SensorManager.java

SystemSensorManager
該類主要實(shí)現(xiàn) SensorManager 控制和數(shù)據(jù)獲取的邏輯。
文件路徑:frameworks/base/core/java/android/hardware/SystemSensorManager.java

android_hardware_SensorManager.cpp
該文件負(fù)責(zé) jave 層和 native 層通信的 JNI 實(shí)現(xiàn)测秸,上層的 Java 代碼通過 JNI 調(diào)用 Native 層提供的服務(wù)疤估。
文件路徑:frameworks/base/core/jni/android_hardware_SensorManager.cpp

SensorManager.cpp
Sensor 在 Native 層的客戶端灾常,負(fù)責(zé)與服務(wù)端 SensorService.cpp 的通信
文件路徑:frameworks/native/libs/gui/SensorManager.cpp

7.4 Android Sensor Native Framework

上圖中的 Server 部分內(nèi)容即為 Android Sensor Native Framwork 的主要構(gòu)成。主要類的主要功能如下:

SensorService.cpp
SensorService 是 Android Sensor Framework 最核心的模塊铃拇,它實(shí)現(xiàn)了主要的 Sensor控制流和數(shù)據(jù)流邏輯钞瀑,完成 Sensor 參數(shù)配置,數(shù)據(jù)分發(fā)慷荔,Client 請求處理等功能雕什。
文件路徑:frameworks/native/services/sensorservice/SensorService.cpp

BinderService
BinderService 是 Android Service 框架的主要類,它提供了 Service 的生命周期管理显晶、進(jìn)程間通信贷岸、請求響應(yīng)處理等功能。Android 中的絕大部分 Service 都會繼承此類磷雇。
文件路徑:frameworks/native/include/binder/BinderService.h

BnSensorServer
該類提供類 Sensor 信息獲取以及 SensorEventConnection 創(chuàng)建的功能偿警。
文件路徑:frameworks/native/include/gui/ISensorServer.h

SensorEventConnection
SensorEventConnection 是 Sensor 數(shù)據(jù)的傳輸通道,當(dāng) Client 開始監(jiān)聽某一個(gè) Sensor 是唯笙,一個(gè)對應(yīng)的 SensorEventConnection 將會被創(chuàng)建螟蒸,Server 端在接收到 Sensor 數(shù)據(jù)后,通過寫入到 SensorEventConnection 傳遞給 Client 端崩掘。
文件路徑:frameworks/native/libs/gui/ISensorEventConnection.cpp

Bittube
該類為單向字節(jié)管道七嫌,提供進(jìn)程間單向數(shù)據(jù)通信功能。SensorEventConnection 是基于 Bittube 實(shí)現(xiàn)的苞慢。
文件路徑:frameworks/native/libs/gui/BitTube.cpp

SensorDevice
該類負(fù)責(zé)管理和維護(hù)系統(tǒng)中的所有 Sensor抄瑟,封裝了 Sensor 的使能、配置枉疼、數(shù)據(jù)讀取等功能。
文件路徑:frameworks/native/services/sensorservice/SensorDevice.cpp

7.5 Android Sensor HAL

Android 定義了一系列 Sensor HAL 接口鞋拟,實(shí)際的 Sensor HAL 庫需要實(shí)現(xiàn)這些接口骂维,主要的接口如下:

7.5.1 SensorList

SensorList 定義了 HAL 層提供的 Sensor,提供 Sensor 類型贺纲、供應(yīng)商航闺、功耗等信息。同時(shí)猴誊,HAL 層需要實(shí)現(xiàn)獲取 SensorList 的回調(diào)接口潦刃。

7.5.2 sensors_module_t

HAL 層需要定義一個(gè) sensors_module_t,供系統(tǒng)在啟動時(shí)加載 Sensor HAL 動態(tài)庫懈叹。sensors_module_t 向上層注冊獲取 SensorList 和獲取 Sensor 控制接口的相關(guān)回調(diào)函數(shù)乖杠。

7.5.3 Sensor 控制和數(shù)據(jù)獲取接口

HAL 層還需要提供實(shí)際控制和獲取 Sensor 數(shù)據(jù)的接口,SensorService 中對 Sensor 的控制和數(shù)據(jù)的獲取最終會調(diào)用到這些接口澄成。

7.6 Android Sensor Framework的初始化流程

7.6.1 Android Sensor Service 初始化

圖片 3

Kernel 在啟動完成后胧洒,會執(zhí)行 init 程序畏吓,該程序接著解析 init.rc 文件,啟動 zygote卫漫,最終會執(zhí)行 Zyoteinit.java 中的 main 函數(shù)菲饼。

在 Zygoteinit 的main 函數(shù)執(zhí)行過程中,會調(diào)用 startSystemServer 接口列赎,該接口最終會調(diào)用 native 層的 nativeforkSystemServer 接口宏悦,進(jìn)而啟動 SystemServer ,調(diào)用其 main 函數(shù)包吝。

在 SystemServer 的 main 函數(shù)中饼煞,會調(diào)用對應(yīng)的 nativeInit 接口。在 nativeInit 中漏策,會創(chuàng)建第一個(gè) SensorService 實(shí)例派哲。當(dāng) SensorService 第一個(gè)實(shí)例創(chuàng)建時(shí),其 onFirstRef 接口將會被調(diào)用掺喻。

圖片 4

在 SensorService 的 onFirstRef 接口中芭届,會創(chuàng)建 SensorDevice 的實(shí)例。在 SensorDevice 的構(gòu)造函數(shù)中感耙,會調(diào)用 hw_get_module 接口加載 Sensor HAL 的動態(tài)庫褂乍,接著調(diào)用 Sensor HAL 提供的 open 接口,執(zhí)行 Sensor HAL 的初始化即硼。 接著 SensorService 通過 SensorDevice逃片,調(diào)用 Sensor HAL 提供的 get_sensors_list 接口,獲取所支持的 Sensor 信息只酥。 而后褥实,SensorService 會創(chuàng)建一個(gè) Looper 和 SensorEventAckReceiver。其中 Looper 用于 enable sensor 后裂允,進(jìn)行數(shù)據(jù)的接收损离;而 SensorEventAckReceiver 則用于在 dispatch wake up sensor event 給上層后,接收上層返回的確認(rèn) ACK绝编。 至此僻澎,SensorService 初始化完畢。

7.6.2 Android Sensor HAL 加載

在 SensorService 創(chuàng)建 SensorDevice 時(shí)十饥,會調(diào)用 hw_get_module 接口加載 SensorHAL 的動態(tài)庫文件窟勃。 在64位的系統(tǒng)中,hw_get_module 接口會在 /vendor/lib64/hw 和 /system/lib64/hw 目錄下搜索 SensorHAL 動態(tài)庫文件逗堵,前者的優(yōu)先級高秉氧。 hw_get_module 會獲取依次獲取 “ro.hardware.sensors”,”ro.hardware”蜒秤,”ro.product.board”谬运,”ro.board.platform”隙赁,”ro.arch” property 的值作為 subname,并以 sensors.subname.so 作為 SensorHAL 動態(tài)庫的文件名梆暖,在上述兩個(gè)目錄中搜索文件是否存在伞访,如果都沒有搜索到,那么最后會用 sensors.default.so 作為文件名轰驳,進(jìn)行搜索厚掷。 當(dāng)搜索到 SensorHAL 的動態(tài)庫文件后,就會調(diào)用 load 接口進(jìn)行加載操作级解。 具體的流程可以查看參考鏈接中的源代碼:

7.6.3 Android Sensor Manager 初始化

APP 在獲取 Sensor 數(shù)據(jù)前冒黑,需要獲取一個(gè) SensorManager 對象。而在其構(gòu)造函數(shù)中勤哗,會先調(diào)用 nativeClassInit 和 nativeGetNextSensor 獲取系統(tǒng)支持的所有 Sensor 的參數(shù)(注抡爹,nativeClassInit 只會調(diào)用一次),包括名稱芒划、類型等參數(shù)冬竟。后續(xù)的相關(guān)接口,會用到這些參數(shù)民逼。

7.7 Android Sensor Framework的數(shù)據(jù)流程分析

圖片 6

當(dāng)上層調(diào)用 registerListener 接口時(shí)泵殴,相應(yīng)的 sensor 就會被 enable。SensorService 在調(diào)用 HAL 提供的 enable 接口前拼苍,會先調(diào)用 batch 接口笑诅,對 sensor 的采樣率、數(shù)據(jù)上報(bào)頻率等進(jìn)行配置疮鲫。另外吆你,如果 sensor 已經(jīng)被 enable 了,那么 SensorService 就只調(diào)用 batch 和 flush 接口俊犯。 SensorService 在 onFirstRef 時(shí)創(chuàng)建了一個(gè) Looper早处,該 Looper 的執(zhí)行線程會調(diào)用 poll 接口,并阻塞在 sensor 的數(shù)據(jù)管道瘫析,當(dāng) sensor 有數(shù)據(jù)返回時(shí),SensorService 會通過 SensorEventQueue 發(fā)送到上層默责,并最終分發(fā)到各個(gè) listener贬循。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市桃序,隨后出現(xiàn)的幾起案子杖虾,更是在濱河造成了極大的恐慌,老刑警劉巖媒熊,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奇适,死亡現(xiàn)場離奇詭異坟比,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嚷往,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門葛账,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人皮仁,你說我怎么就攤上這事籍琳。” “怎么了贷祈?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵趋急,是天一觀的道長。 經(jīng)常有香客問我势誊,道長呜达,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任粟耻,我火速辦了婚禮查近,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勋颖。我一直安慰自己嗦嗡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布饭玲。 她就那樣靜靜地躺著侥祭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茄厘。 梳的紋絲不亂的頭發(fā)上矮冬,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音次哈,去河邊找鬼胎署。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窑滞,可吹牛的內(nèi)容都是我干的琼牧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哀卫,長吁一口氣:“原來是場噩夢啊……” “哼巨坊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起此改,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤趾撵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后共啃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體占调,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡暂题,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了究珊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薪者。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖苦银,靈堂內(nèi)的尸體忽然破棺而出啸胧,到底是詐尸還是另有隱情,我是刑警寧澤幔虏,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布纺念,位于F島的核電站,受9級特大地震影響想括,放射性物質(zhì)發(fā)生泄漏陷谱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一瑟蜈、第九天 我趴在偏房一處隱蔽的房頂上張望烟逊。 院中可真熱鬧,春花似錦铺根、人聲如沸宪躯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽访雪。三九已至,卻和暖如春掂林,著一層夾襖步出監(jiān)牢的瞬間臣缀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工泻帮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留精置,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓锣杂,卻偏偏與公主長得像脂倦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子元莫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容