一、傳感器介紹
利用 Android 傳感器框架,您可以訪問(wèn)多種類型的傳感器。有些傳感器基于硬件,有些基于軟件?;谟布膫鞲衅魇莾?nèi)置在手機(jī)或平板設(shè)備中的物理組件。這類傳感器通過(guò)直接測(cè)量特定的環(huán)境屬性(如加速度、地磁場(chǎng)強(qiáng)度或角度變化)來(lái)采集數(shù)據(jù)。基于軟件的傳感器不是物理設(shè)備,它們只是模仿基于硬件的傳感器?;谲浖膫鞲衅鲝囊粋€(gè)或多個(gè)基于硬件的傳感器獲取數(shù)據(jù),有時(shí)被稱為虛擬傳感器或合成傳感器。比如線性加速度傳感器和重力傳感器就是基于軟件的傳感器。
1.1 Android 平臺(tái)三大類傳感器
-
動(dòng)態(tài)傳感器
這類傳感器測(cè)量三個(gè)軸向上的加速力和旋轉(zhuǎn)力。這個(gè)類別中包含加速度計(jì)、重力傳感器、陀螺儀和旋轉(zhuǎn)矢量傳感器。
-
環(huán)境傳感器
這類傳感器測(cè)量各種環(huán)境參數(shù),如環(huán)境氣溫、氣壓、照度和濕度。這個(gè)類別中包含氣壓計(jì)、光度計(jì)和溫度計(jì)。
-
位置傳感器
這類傳感器測(cè)量設(shè)備的物理位置。這個(gè)類別中包含屏幕方向傳感器和磁力計(jì)。
1.2 Android 平臺(tái)支持的傳感器
傳感器 | 類型 | 說(shuō)明 | 常見(jiàn)用途 |
---|---|---|---|
TYPE_ACCELEROMETER |
硬件 | 測(cè)量在所有三個(gè)物理軸向(x、y 和 z)上施加在設(shè)備上的加速力(包括重力),以 m/s2 為單位。 | 動(dòng)態(tài)檢測(cè)(搖晃、傾斜等)。 |
TYPE_AMBIENT_TEMPERATURE |
硬件 | 以攝氏度 (°C) 為單位測(cè)量環(huán)境室溫。請(qǐng)參見(jiàn)下面的備注。 | 監(jiān)測(cè)氣溫。 |
TYPE_GRAVITY |
軟件或硬件 | 測(cè)量在所有三個(gè)物理軸向(x、y、z)上施加在設(shè)備上的重力,單位為 m/s2。 | 動(dòng)態(tài)檢測(cè)(搖晃、傾斜等)。 |
TYPE_GYROSCOPE |
硬件 | 測(cè)量設(shè)備在三個(gè)物理軸向(x、y 和 z)上的旋轉(zhuǎn)速率,以 rad/s 為單位。 | 旋轉(zhuǎn)檢測(cè)(旋轉(zhuǎn)、轉(zhuǎn)動(dòng)等)。 |
TYPE_LIGHT |
硬件 | 測(cè)量環(huán)境光級(jí)(照度),以 lx 為單位。 | 控制屏幕亮度。 |
TYPE_LINEAR_ACCELERATION |
軟件或硬件 | 測(cè)量在所有三個(gè)物理軸向(x、y 和 z)上施加在設(shè)備上的加速力(不包括重力),以 m/s2 為單位。 | 監(jiān)測(cè)單個(gè)軸向上的加速度。 |
TYPE_MAGNETIC_FIELD |
硬件 | 測(cè)量所有三個(gè)物理軸向(x、y、z)上的環(huán)境地磁場(chǎng),以 μT 為單位。 | 創(chuàng)建羅盤。 |
TYPE_ORIENTATION |
軟件 | 測(cè)量設(shè)備圍繞所有三個(gè)物理軸(x、y、z)旋轉(zhuǎn)的度數(shù)。從 API 級(jí)別 3 開始,您可以結(jié)合使用重力傳感器、地磁場(chǎng)傳感器和 getRotationMatrix() 方法來(lái)獲取設(shè)備的傾角矩陣和旋轉(zhuǎn)矩陣。 |
確定設(shè)備位置。 |
TYPE_PRESSURE |
硬件 | 測(cè)量環(huán)境氣壓,以 hPa 或 mbar 為單位。 | 監(jiān)測(cè)氣壓變化。 |
TYPE_PROXIMITY |
硬件 | 測(cè)量物體相對(duì)于設(shè)備顯示屏幕的距離,以 cm 為單位。該傳感器通常用于確定手機(jī)是否被舉到人的耳邊。 | 通話過(guò)程中手機(jī)的位置。 |
TYPE_RELATIVE_HUMIDITY |
硬件 | 測(cè)量環(huán)境的相對(duì)濕度,以百分比 (%) 表示。 | 監(jiān)測(cè)露點(diǎn)、絕對(duì)濕度和相對(duì)濕度。 |
TYPE_ROTATION_VECTOR |
軟件或硬件 | 通過(guò)提供設(shè)備旋轉(zhuǎn)矢量的三個(gè)元素來(lái)檢測(cè)設(shè)備的屏幕方向。 | 動(dòng)態(tài)檢測(cè)和旋轉(zhuǎn)檢測(cè)。 |
TYPE_TEMPERATURE |
硬件 | 測(cè)量設(shè)備的溫度,以攝氏度 (°C) 為單位。該傳感器的實(shí)現(xiàn)因設(shè)備而異。在 API 級(jí)別 14 中,該傳感器已被 TYPE_AMBIENT_TEMPERATURE 傳感器取代 |
監(jiān)測(cè)溫度。 |
很少有 Android 設(shè)備擁有所有類型的傳感器。例如,大多數(shù)手機(jī)設(shè)備和平板電腦都有加速度計(jì)和磁力計(jì),但很少有氣壓計(jì)或溫度計(jì)。此外,一個(gè)設(shè)備可以有多個(gè)特定類型的傳感器。例如,一個(gè)設(shè)備可以有兩個(gè)重力傳感器,分別具有不同的量程。
1.3 傳感器框架
可以利用 Android 傳感器框架來(lái)訪問(wèn)這些傳感器并獲取傳感器的原始數(shù)據(jù)。傳感器框架是 android.hardware
軟件包的一部分,包含了以下類和接口:
-
SensorManager
您可以使用這個(gè)類來(lái)創(chuàng)建傳感器服務(wù)的實(shí)例。該類提供了各種方法來(lái)訪問(wèn)和列出傳感器,注冊(cè)和取消注冊(cè)傳感器事件監(jiān)聽器,以及獲取屏幕方向信息。它還提供了幾個(gè)傳感器常量,用于報(bào)告?zhèn)鞲衅骶_度,設(shè)置數(shù)據(jù)采集頻率和校準(zhǔn)傳感器。
-
Sensor
您可以使用這個(gè)類來(lái)創(chuàng)建特定傳感器的實(shí)例。該類提供了各種方法來(lái)確定傳感器的特性。
-
SensorEvent
系統(tǒng)使用這個(gè)類來(lái)創(chuàng)建傳感器事件對(duì)象,該對(duì)象提供有關(guān)傳感器事件的信息。傳感器事件對(duì)象中包含以下信息:原始傳感器數(shù)據(jù)、生成事件的傳感器類型、數(shù)據(jù)的準(zhǔn)確度和事件的時(shí)間戳。
-
SensorEventListener
您可以使用此接口創(chuàng)建兩種回調(diào)方法,以在傳感器值或傳感器精確度發(fā)生變化時(shí)接收通知(傳感器事件)。
在典型的應(yīng)用中,您可以使用這些與傳感器相關(guān)的 API 來(lái)執(zhí)行兩個(gè)基本任務(wù):
-
識(shí)別傳感器和傳感器特性
如果應(yīng)用具有依賴于特定傳感器類型或特性的功能,則在運(yùn)行時(shí)識(shí)別傳感器和傳感器特性非常有用。例如,您可能希望識(shí)別設(shè)備上的所有傳感器,以便于停用依賴于不存在的傳感器的應(yīng)用功能。同樣,您可能希望識(shí)別特定類型的所有傳感器,以便選擇可以為應(yīng)用帶來(lái)最佳性能的傳感器實(shí)現(xiàn)。
-
監(jiān)控傳感器事件
您可以通過(guò)監(jiān)控傳感器事件來(lái)獲取原始傳感器數(shù)據(jù)。每當(dāng)傳感器檢測(cè)到它所測(cè)量的參數(shù)發(fā)生變化時(shí),就會(huì)發(fā)生傳感器事件。傳感器事件為您提供 4 項(xiàng)信息:觸發(fā)事件的傳感器的名稱、事件的時(shí)間戳、事件的準(zhǔn)確度以及觸發(fā)事件的原始傳感器數(shù)據(jù)。
二、傳感器的使用
2.1 識(shí)別傳感器和傳感器特性
Android 傳感器框架提供了幾個(gè)方法,可讓您在運(yùn)行時(shí)輕松確定設(shè)備上有哪些傳感器。該 API 還提供了相關(guān)方法來(lái)確定每個(gè)傳感器的特性,例如最大量程、分辨率和功率要求。
要識(shí)別設(shè)備上的傳感器,您首先需要獲得對(duì)傳感器服務(wù)的引用。為此,您可以調(diào)用 getSystemService()
方法并傳入 SENSOR_SERVICE
參數(shù)來(lái)創(chuàng)建 SensorManager
類的實(shí)例。例如:
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
接下來(lái),您可以調(diào)用 getSensorList()
方法并使用 TYPE_ALL
常量來(lái)獲取設(shè)備上每種傳感器的列表。例如:
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
如果您想列出特定類型的所有傳感器,可以使用其他常量來(lái)代替 TYPE_ALL
,例如 TYPE_GYROSCOPE
、TYPE_LINEAR_ACCELERATION
或 TYPE_GRAVITY
。
您還可以使用 getDefaultSensor()
方法并傳入特定傳感器的類型常量,來(lái)確定設(shè)備上是否存在相關(guān)類型的傳感器。如果設(shè)備上有多個(gè)特定類型的傳感器,則必須將其中一個(gè)指定為默認(rèn)傳感器。如果沒(méi)有指定默認(rèn)傳感器,則該方法調(diào)用會(huì)返回 null,這表示設(shè)備沒(méi)有該類型的傳感器。例如,以下代碼會(huì)檢查設(shè)備上是否有磁力計(jì):
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
// Success! There's a magnetometer.
} else {
// Failure! No magnetometer.
}
除了列出設(shè)備上的傳感器之外,您還可以使用 Sensor
類的公共方法確定單個(gè)傳感器的功能和屬性。如果您希望應(yīng)用根據(jù)設(shè)備上可用的傳感器或傳感器功能表現(xiàn)出不同的行為,這會(huì)非常有用。例如,您可以使用 getResolution()
和 getMaximumRange()
方法來(lái)獲得傳感器的分辨率和最大量程。您也可以使用 getPower()
方法來(lái)獲得傳感器的電源要求。
2.2 針對(duì)不同制造商的傳感器或傳感器的不同版本優(yōu)化
如果您希望針對(duì)不同制造商的傳感器或傳感器的不同版本優(yōu)化您的應(yīng)用,有兩種公共方法特別有用。例如,如果您的應(yīng)用需要監(jiān)控用戶手勢(shì)(例如傾斜和搖晃),您可以針對(duì)帶有特定供應(yīng)商的重力傳感器的新款設(shè)備創(chuàng)建一組數(shù)據(jù)過(guò)濾規(guī)則和優(yōu)化配置,而針對(duì)沒(méi)有重力傳感器、只有加速度計(jì)的設(shè)備創(chuàng)建另一組數(shù)據(jù)過(guò)濾規(guī)則和優(yōu)化配置。
以下代碼示例展示了如何使用 getVendor()
和 getVersion()
方法來(lái)執(zhí)行此操作。在本例中,我們要查找一個(gè)將 Google LLC 列為供應(yīng)商、版本號(hào)為 3 的重力傳感器。如果設(shè)備上沒(méi)有該傳感器,我們會(huì)嘗試使用加速度計(jì)。
private SensorManager sensorManager;
private Sensor mSensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;
if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
for(int i=0; i<gravSensors.size(); i++) {
if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
(gravSensors.get(i).getVersion() == 3)){
// Use the version 3 gravity sensor.
mSensor = gravSensors.get(i);
}
}
}
if (mSensor == null){
// Use the accelerometer.
if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
} else{
// Sorry, there are no accelerometers on your device.
// You can't play this game.
}
}
另一個(gè)有用的方法是 getMinDelay()
,它會(huì)返回傳感器可用于檢測(cè)數(shù)據(jù)的最小時(shí)間間隔(以微秒為單位)。如果 getMinDelay()
方法返回非零值,則表示相應(yīng)傳感器為流式傳感器。流式傳感器是在 Android 2.3(API 級(jí)別 9)中引入的,這類傳感器會(huì)定期檢測(cè)數(shù)據(jù)。如果調(diào)用 getMinDelay()
方法時(shí),傳感器返回 0,則說(shuō)明傳感器不是流式傳感器,因?yàn)樗鼉H在所檢測(cè)的參數(shù)發(fā)生變化時(shí)才會(huì)報(bào)告數(shù)據(jù)。
getMinDelay()
方法可用于確定傳感器采集數(shù)據(jù)的最高頻率。如果應(yīng)用中的某些功能需要較高的數(shù)據(jù)采集頻率或流式傳感器,則可以使用此方法確定傳感器是否滿足這些要求,然后相應(yīng)地啟用或停用應(yīng)用中的相關(guān)功能。
2.3 監(jiān)控傳感器事件
要監(jiān)控原始傳感器數(shù)據(jù),您需要實(shí)現(xiàn)兩個(gè)通過(guò) SensorEventListener
接口公開的回調(diào)方法:onAccuracyChanged()
和 onSensorChanged()
。Android 系統(tǒng)會(huì)在發(fā)生以下情況時(shí)調(diào)用這兩個(gè)方法:
-
傳感器的準(zhǔn)確度發(fā)生了變化。
在這種情況下,系統(tǒng)會(huì)調(diào)用
onAccuracyChanged()
方法,為您提供對(duì)于發(fā)生變化的Sensor
對(duì)象的引用以及傳感器的新準(zhǔn)確度。準(zhǔn)確度由以下 4 個(gè)狀態(tài)常量之一表示:SENSOR_STATUS_ACCURACY_LOW
、SENSOR_STATUS_ACCURACY_MEDIUM
、SENSOR_STATUS_ACCURACY_HIGH
或SENSOR_STATUS_UNRELIABLE
。 -
傳感器報(bào)告了新值。
在這種情況下,系統(tǒng)會(huì)調(diào)用
onSensorChanged()
方法,為您提供SensorEvent
對(duì)象。SensorEvent
對(duì)象包含關(guān)于新傳感器數(shù)據(jù)的信息,包括:數(shù)據(jù)的準(zhǔn)確度、生成數(shù)據(jù)的傳感器、生成數(shù)據(jù)的時(shí)間戳以及傳感器記錄的新數(shù)據(jù)。
以下代碼展示了如何使用 onSensorChanged()
方法監(jiān)控光傳感器的數(shù)據(jù)。在本示例中,原始傳感器數(shù)據(jù)作為 sensor_data
顯示在 main.xml 文件中定義的 TextView
中。
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor mLight;
@Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
@Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
float lux = event.values[0];
// Do something with this sensor value.
}
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
}
在本示例中,在調(diào)用 registerListener()
方法時(shí)指定了默認(rèn)數(shù)據(jù)延遲 (SENSOR_DELAY_NORMAL
)。數(shù)據(jù)延遲(或采樣率)控制傳感器事件通過(guò) onSensorChanged()
回調(diào)方法發(fā)送到應(yīng)用的時(shí)間間隔。默認(rèn)數(shù)據(jù)延遲采用 200,000 微秒的延遲,適用于監(jiān)控典型的屏幕方向變化。您可以指定其他數(shù)據(jù)延遲,比如 SENSOR_DELAY_GAME
(延遲 20,000 微秒)、SENSOR_DELAY_UI
(延遲 60,000 微秒),或 SENSOR_DELAY_FASTEST
(延遲 0 微秒)。從 Android 3.0(API 級(jí)別 11)開始,您還可以將延遲指定為以微秒為單位的絕對(duì)值。
您指定的延遲只是建議的延遲。Android 系統(tǒng)和其他應(yīng)用可以更改此延遲。最佳做法是指定盡可能大的延遲,因?yàn)橄到y(tǒng)通常會(huì)使用比您指定的延遲更小的延遲(也就是說(shuō),您應(yīng)該選擇能夠滿足應(yīng)用需求的最低采樣率)。使用更大的延遲可以降低處理器的負(fù)載,從而降低功耗。
沒(méi)有任何公共方法可以確定傳感器框架向您的應(yīng)用發(fā)送傳感器事件的頻率,但是,您可以使用與每個(gè)傳感器事件關(guān)聯(lián)的時(shí)間戳來(lái)計(jì)算幾個(gè)事件的采樣率。采樣率(延遲)一旦設(shè)置,就不應(yīng)該再更改。如果由于某種原因確實(shí)需要更改延遲,則必須取消注冊(cè)再重新注冊(cè)傳感器監(jiān)聽器。
另外還需要注意的是,本示例使用 onResume()
和 onPause()
回調(diào)方法來(lái)注冊(cè)和取消注冊(cè)傳感器事件監(jiān)聽器。最佳的做法是始終停用不需要的傳感器,特別是在活動(dòng)處于暫停狀態(tài)時(shí)。如果不這樣做,可能會(huì)在幾小時(shí)內(nèi)將電池電量耗盡,因?yàn)橛行﹤鞲衅鞯碾娏啃枨蠛艽?,可以很快耗盡電池電量。當(dāng)屏幕關(guān)閉時(shí),系統(tǒng)不會(huì)自動(dòng)停用傳感器。
2.4 處理不同的傳感器配置
Android 沒(méi)有為設(shè)備指定標(biāo)準(zhǔn)的傳感器配置,這意味著設(shè)備制造商可以在其 Android 設(shè)備中采用任何想要的傳感器配置。因此,設(shè)備可以包含采用各種配置的各種傳感器。如果您的應(yīng)用依賴于特定類型的傳感器,則必須確保設(shè)備上存在該傳感器,這樣您的應(yīng)用才能成功運(yùn)行。
有兩種方法可以確保設(shè)備上存在特定的傳感器:
- 在運(yùn)行時(shí)檢測(cè)傳感器,并根據(jù)需要啟用或停用應(yīng)用功能。
- 使用 Google Play 過(guò)濾器定位具有特定傳感器配置的設(shè)備。
下面將分別討論這兩種方法。
在運(yùn)行時(shí)檢測(cè)傳感器
如果您的應(yīng)用使用特定類型的傳感器,但不依賴于它,則可以使用傳感器框架在運(yùn)行時(shí)檢測(cè)傳感器,然后根據(jù)需要停用或啟用應(yīng)用功能。例如,導(dǎo)航應(yīng)用可能會(huì)使用溫度傳感器、壓力傳感器、GPS 傳感器和地磁場(chǎng)傳感器來(lái)顯示溫度、氣壓、位置和羅盤方位。如果設(shè)備沒(méi)有壓力傳感器,您可以使用傳感器框架在運(yùn)行時(shí)檢測(cè)壓力傳感器的缺失,然后停用應(yīng)用界面中顯示壓力的部分。例如,以下代碼會(huì)檢查設(shè)備上是否有壓力傳感器:
private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
// Success! There's a pressure sensor.
} else {
// Failure! No pressure sensor.
}
使用 Google Play 過(guò)濾器定位特定的傳感器配置
如果您要在 Google Play 上發(fā)布應(yīng)用,您可以在清單文件中使用
元素,以對(duì)不具備適合您應(yīng)用的傳感器配置的設(shè)備屏蔽您的應(yīng)用。<uses-feature>
元素有幾個(gè)硬件描述符,可讓您根據(jù)是否存在特定傳感器來(lái)過(guò)濾應(yīng)用。您可以列出的傳感器包括:加速度計(jì)、氣壓計(jì)、羅盤(地磁場(chǎng))、陀螺儀、光傳感器和距離傳感器。以下清單示例條目會(huì)對(duì)沒(méi)有加速度計(jì)的設(shè)備屏蔽應(yīng)用:
<uses-feature android:name="android.hardware.sensor.accelerometer"
android:required="true" />
如果您將此元素和描述符添加到應(yīng)用的清單中,那么只有當(dāng)用戶的設(shè)備具有加速度計(jì)時(shí),他們才會(huì)在 Google Play 上看到您的應(yīng)用。
僅當(dāng)您的應(yīng)用完全依賴于特定傳感器時(shí),才應(yīng)將描述符設(shè)置為 android:required="true"
。如果您的應(yīng)用使用某種傳感器來(lái)實(shí)現(xiàn)某項(xiàng)功能,但沒(méi)有該傳感器也可以運(yùn)行,那么您就應(yīng)該在 <uses-feature>
元素中列出該傳感器,但將描述符設(shè)置為 android:required="false"
。這樣可以確保設(shè)備即使沒(méi)有該傳感器也可以安裝您的應(yīng)用。這也是幫助您跟蹤應(yīng)用所使用的功能的最佳項(xiàng)目管理方法。請(qǐng)記住,如果您的應(yīng)用使用特定的傳感器,但沒(méi)有該傳感器也能運(yùn)行,那么您就應(yīng)該在運(yùn)行時(shí)檢測(cè)傳感器,并根據(jù)需要停用或啟用應(yīng)用功能。
2.5 傳感器坐標(biāo)系
通常,傳感器框架使用標(biāo)準(zhǔn)的 3 軸坐標(biāo)系來(lái)表示數(shù)據(jù)值。對(duì)于大多數(shù)傳感器,當(dāng)設(shè)備處于默認(rèn)屏幕方向時(shí),會(huì)相對(duì)于設(shè)備屏幕來(lái)定義坐標(biāo)系。
當(dāng)設(shè)備處于默認(rèn)屏幕方向時(shí),X 軸為水平向右延伸,Y 軸為垂直向上延伸,Z 軸為垂直于屏幕向外延伸。在此坐標(biāo)系中,屏幕后面的坐標(biāo)將具有負(fù) Z 值。以下傳感器使用此坐標(biāo)系:
- 加速度傳感器
- 重力傳感器
- 陀螺儀
- 線性加速度傳感器
- 地磁場(chǎng)傳感器
關(guān)于此坐標(biāo)系,特別需要注意的一點(diǎn)就是當(dāng)設(shè)備的屏幕方向改變時(shí),坐標(biāo)軸不會(huì)轉(zhuǎn)換,也就是說(shuō),傳感器的坐標(biāo)系不會(huì)隨著設(shè)備的移動(dòng)而改變。此行為與 OpenGL 坐標(biāo)系的行為是相同的。
還需要注意的一點(diǎn)是,您的應(yīng)用不能假設(shè)設(shè)備的自然(默認(rèn))屏幕方向是豎屏。許多平板設(shè)備的自然屏幕方向?yàn)闄M屏。傳感器坐標(biāo)系始終基于設(shè)備的自然屏幕方向。
最后,如果您的應(yīng)用將傳感器數(shù)據(jù)對(duì)應(yīng)到屏幕顯示,您需要使用 getRotation()
方法確定屏幕的旋轉(zhuǎn)度,然后使用 remapCoordinateSystem()
方法將傳感器坐標(biāo)映射到屏幕坐標(biāo)。即使您的清單指定了僅限豎屏顯示,您也需要這樣做。
有些傳感器和方法使用的坐標(biāo)系基于世界參照系(而不是設(shè)備參照系)。這些傳感器和方法返回的數(shù)據(jù)表示設(shè)備相對(duì)于地球的運(yùn)動(dòng)或位置。如需了解詳情,請(qǐng)參閱
getOrientation()
方法、getRotationMatrix()
方法、屏幕方向傳感器和旋轉(zhuǎn)矢量傳感器。
2.6 訪問(wèn)和使用傳感器的最佳做法
在設(shè)計(jì)傳感器實(shí)現(xiàn)時(shí),請(qǐng)務(wù)必遵循本節(jié)介紹的指導(dǎo)原則。若要使用傳感器框架訪問(wèn)傳感器和采集傳感器數(shù)據(jù),建議將這些指導(dǎo)原則視為最佳做法。
僅在前臺(tái)采集傳感器數(shù)據(jù)
在搭載 Android 9(API 級(jí)別 28)或更高版本的設(shè)備上,在后臺(tái)運(yùn)行的應(yīng)用具有以下限制:
- 采用連續(xù)報(bào)告模式的傳感器(如加速度計(jì)和陀螺儀)不會(huì)收到事件。
- 使用變化時(shí)觸發(fā)或單次報(bào)告模式的傳感器不會(huì)收到事件。
考慮到這些限制,最好是在應(yīng)用于前臺(tái)運(yùn)行或作為前臺(tái)服務(wù)的一部分時(shí)檢測(cè)傳感器事件。
取消注冊(cè)傳感器監(jiān)聽器文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-769187.html
請(qǐng)確保在不使用傳感器或傳感器活動(dòng)暫停時(shí)取消注冊(cè)傳感器的監(jiān)聽器。注冊(cè)傳感器監(jiān)聽器后,只要不取消注冊(cè)傳感器,那么即使監(jiān)聽器的活動(dòng)已暫停,傳感器仍會(huì)繼續(xù)采集數(shù)據(jù)并消耗電池資源。以下代碼展示了如何使用 onPause()
方法來(lái)取消注冊(cè)監(jiān)聽器:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-769187.html
private SensorManager sensorManager;
...
@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
到了這里,關(guān)于傳感器:探索Android中的傳感器功能與使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!