大多數 Android 裝置都內建感應器,可測量動作、螢幕方向, 和各種環境條件這些感應器能夠提供高用量的原始資料 。如果您想監控 3D 裝置的移動或 或監控裝置附近的環境變化。舉例來說 遊戲可能會追蹤來自裝置重力感應器的讀數,藉此推斷複雜的使用者手勢 以及動作,例如傾斜、搖晃、旋轉或搖擺。同樣地,天氣應用程式可能會使用 裝置的溫度感應器和濕度感應器,用於計算並回報露點或旅遊 應用程式可能會使用地磁場感應器和加速計回報指南針 方針。
請參閱下列相關資源:
Android 平台支援以下三種感應器:
- 動作感應器
這些感應器會沿著三軸測量加速力和旋轉力,這個 類別包括加速計、重力感應器、陀螺儀和旋轉向量 感應器。
- 環境感應器
這些感應器會測量多種環境參數,例如環境氣溫 包括壓力、照明和濕度這個類別包括氣壓計、光量計 溫度計
- 位置感應器
這些感應器會測量裝置的實際位置,這個類別包括 螢幕方向感應器和磁力儀。
如要存取裝置上的感應器,並擷取原始感應器資料,請使用 Android 感應器架構感應器架構提供多種類別和介面,協助您執行更廣泛的 代表各式各樣的感應器工作舉例來說,您可以使用感應器架構執行以下操作:
- 確認裝置可用的感應器。
- 決定個別感應器的功能,例如最大範圍、製造商、功率 需求和解決方法
- 取得原始感應器資料,並定義取得感應器資料的最低速率。
- 註冊及取消註冊可監控感應器異動的感應器事件監聽器。
本主題將概略說明 Android 平台可用的感應器。 並介紹感應器架構。
感應器簡介
Android 感應器架構可讓你存取多種類型的感應器。其中一些感應器 有些則是以軟體為基礎硬體式感應器是實體元件 下載到手機或平板電腦裝置上。他們直接評估特定環境,藉此取得資料 ,例如加速度、地磁場強度或角度變化。軟體式 雖然感應器會模仿硬體感應器,但並非實體裝置。軟體式感應器 資料衍生自一或多個硬體式感應器,有時也稱為虛擬 感應器或合成感應器線性加速感應器和重力感應器是 軟體式感應器表 1 摘要列出 Android 支援的感應器 平台。
只有少數搭載 Android 系統的裝置搭載所有類型的感應器。例如大部分的手機裝置和 平板電腦具有加速計和磁力儀,但這些裝置擁有較少的裝置 氣壓計或溫度計此外,單一裝置可以有多個特定類型的感應器。適用對象 舉例來說,一部裝置可以有兩個重力感應器,每個感應器的重力範圍皆不同
感應器 | 類型 | 說明 | 常見用途 |
---|---|---|---|
TYPE_ACCELEROMETER |
硬體 | 測量裝置套用至裝置的加速度 (以 m/s2 為單位) 這三個物理軸 (x、y 和 z),包括重力的力量 | 動作偵測 (搖動、傾斜等)。 |
TYPE_AMBIENT_TEMPERATURE |
硬體 | 測量環境室溫,以攝氏度為單位。詳情請參閱下方的附註。 | 監測溫度。 |
TYPE_GRAVITY |
軟體或硬體 | 測量套用至所有裝置的重力 (公尺/秒) 即三個實體軸 (x、y、z)。 | 動作偵測 (搖動、傾斜等)。 |
TYPE_GYROSCOPE |
硬體 | 測量裝置的旋轉速率 物理軸 (x、y 和 z)。 | 旋轉偵測 (傾斜、轉動等)。 |
TYPE_LIGHT |
硬體 | 測量 Lx 的環境光度 (照明)。 | 控制螢幕亮度。 |
TYPE_LINEAR_ACCELERATION |
軟體或硬體 | 以 m/s2 為單位測量加速度 已套用至 這三個物理軸 (x、y 和 z),不含重力力。 | 沿著單一軸線監控加速。 |
TYPE_MAGNETIC_FIELD |
硬體 | 測量全部三個物理軸 (x、y、z) 的環境磁場 μT。 | 建立指南針。 |
TYPE_ORIENTATION |
軟體 | 測量裝置在三個物理軸 (x、y、z) 周圍的旋轉角度。
從 API 級別 3 開始,您可以取得
測量到的裝置使用重力感應器
以及地磁場感應器和
getRotationMatrix()
方法。 |
正在判斷裝置位置。 |
TYPE_PRESSURE |
硬體 | 測量環境氣壓 (以 hPa 或 mbar 為單位)。 | 監測氣壓變化。 |
TYPE_PROXIMITY |
硬體 | 測量物件與 (以公分為單位) 相對於裝置畫面的距離 裝置。這類感應器通常用於判斷手機是否 某人的耳朵 | 通話期間的手機位置。 |
TYPE_RELATIVE_HUMIDITY |
硬體 | 測量相對環境濕度百分比 (百分比)。 | 監測露點、絕對濕度和相對濕度。 |
TYPE_ROTATION_VECTOR |
軟體或硬體 | 提供裝置螢幕方向的三個元素,藉此測量裝置的方向 | 動作偵測和旋轉偵測。 |
TYPE_TEMPERATURE |
硬體 | 測量裝置溫度,以攝氏度為單位。這部感應器
導入方式會因裝置而異
這個感應器已替換成「TYPE_AMBIENT_TEMPERATURE 」感應器
API 級別 14 |
用於監測溫度。 |
感應器架構
如要存取這些感應器,並運用 Android 感應器架構取得原始感應器資料,
感應器架構是 android.hardware
套件的一部分,包含下列內容:
類別和介面:
SensorManager
- 你可以使用這個類別來建立感應器服務的例項。這個類別提供 存取及列出感應器、註冊及取消註冊感應器事件的各種方法 以及取得方向資訊。這個類別也提供多個感應器常數 包括回報感應器準確率、設定資料擷取率及校正感應器。
Sensor
- 你可以使用這個類別建立特定感應器的例項。這個類別提供多種 可讓您判斷感應器的能力
SensorEvent
- 系統會使用這個類別建立感應器事件物件,藉此提供 也就是感應器事件感應器事件物件包含下列資訊:原始感應器資料、 產生事件的感應器類型、資料準確度,以及 活動。
SensorEventListener
- 您可以使用這個介面建立兩種用來接收通知的回呼方法 (感應器 事件)。
在一般應用程式中,您會使用下列感應器相關 API 來執行兩項基本工作:
- 找出感應器和感應器功能
如果您的應用程式含有 需要特定感應器類型或功能才能運作的功能。舉例來說 找出裝置上的所有感應器,並停用任何應用程式功能 並仰賴不存在的感應器同樣地,您也可以找出所有感應器 方便您選擇具有最佳效能的感應器實作方式 應用程式。
- 監控感應器事件
但監控感應器事件是取得原始感應器資料的方式。每次發生感應器事件時 感應器偵測到正在測量的參數發生變化。「感應器事件」 包含四項資訊:觸發事件的感應器名稱、 事件的時間戳記、事件準確率,以及觸發的原始感應器資料 活動。
可用感應器
雖然感應器可用的感應器因裝置而異,但也可能因 Android 裝置而異。 版本。這是因為 Android 感應器在 發布新版本例如,Android 1.5 (API 級別 3) 導入了許多感應器, 未實作,且在 Android 2.3 (API 級別 9) 之前無法使用。同樣地 Android 2.3 (API 級別 9) 和 Android 4.0 (API 級別 14) 導入了數個感應器。兩條 感應器已淘汰,並由更優異的新版感應器取代。
表 2 摘要列出各平台每個感應器的可用性。只有四個 是因為這些平台涉及感應器異動搭載全新設計的感應器 列為已淘汰的後續平台仍可提供 感應器在裝置上,符合 Android 的前瞻相容性政策。
感應器 | Android 4.0 (API 級別 14) |
Android 2.3 (API 級別 9) |
Android 2.2 (API 級別 8) |
Android 1.5 (API 級別 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
是 | 是 | 是 | 是 |
TYPE_AMBIENT_TEMPERATURE |
是 | 不適用 | 不適用 | 不適用 |
TYPE_GRAVITY |
是 | 是 | 不適用 | 不適用 |
TYPE_GYROSCOPE |
是 | 是 | 不適用1 | 不適用1 |
TYPE_LIGHT |
是 | 是 | 是 | 是 |
TYPE_LINEAR_ACCELERATION |
是 | 是 | 不適用 | 不適用 |
TYPE_MAGNETIC_FIELD |
是 | 是 | 是 | 是 |
TYPE_ORIENTATION |
是2 | 是2 | 是2 | 是 |
TYPE_PRESSURE |
是 | 是 | 不適用1 | 不適用1 |
TYPE_PROXIMITY |
是 | 是 | 是 | 是 |
TYPE_RELATIVE_HUMIDITY |
是 | 不適用 | 不適用 | 不適用 |
TYPE_ROTATION_VECTOR |
是 | 是 | 不適用 | 不適用 |
TYPE_TEMPERATURE |
是2 | 是 | 是 | 是 |
1 已在 Android 1.5 (API 級別) 中新增這個感應器類型 3)、 但不適用於 Android 2.3 (API 級別 9) 版本。
2 這個感應器雖可以使用,但已問世 已淘汰。
識別感應器和感應器功能
Android 感應器架構提供數種方法,可讓您輕鬆判斷 執行階段,此功能會播放裝置上的感應器資料。API 也提供方法,可讓您判斷 例如感應器的最大範圍、解析度和功率 Google Cloud 就是最佳選擇
如要辨識裝置中的感應器,請先取得感應器的參照
課程中也會快速介紹 Memorystore
這是 Google Cloud 的全代管 Redis 服務方法是透過以下方式建立 SensorManager
類別的例項:
呼叫 getSystemService()
方法並傳遞
SENSOR_SERVICE
引數中。例如:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
接下來,你可以呼叫
getSensorList()
方法並使用 TYPE_ALL
常數。例如:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
如要列出指定類型的所有感應器,您可以使用另一個常數,而非
TYPE_ALL
,例如 TYPE_GYROSCOPE
、
TYPE_LINEAR_ACCELERATION
,或
TYPE_GRAVITY
。
您也可以使用 getDefaultSensor()
方法並傳入類型,判斷裝置上是否存在特定類型的感應器
特定感應器的常數。如果裝置有多個指定類型的感應器,
必須將感應器指派為預設感應器。如果指定的預設感應器不存在
方法呼叫會傳回空值,表示裝置沒有該類型
感應器。舉例來說,以下程式碼會檢查裝置上是否有磁力儀:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) { // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Java
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. }
注意:Android 不需要裝置製造商製作任何產品 安裝在 Android 裝置上,因此能支援許多不同類型的感應器 感應器設定
除了列出裝置上的感應器之外,您也可以使用
Sensor
類別用來判斷個別功能的能力和屬性
感應器。如果您希望應用程式根據不同的感應器或
只有裝置才能支援感應器的功能例如,您可以使用 getResolution()
和 getMaximumRange()
方法,以取得感應器的解析度和最大測量範圍。您也可以使用
getPower()
方法,用於取得感應器的電源需求。
如果您要針對應用程式最佳化
不同製造商的感應器或感應器的不同版本舉例來說
監控傾斜和搖動等使用者手勢,您可以建立一組資料篩選器
針對使用特定廠商重力感應器的新型裝置制定規則和最佳化作業
一組資料篩選規則,以及針對沒有重力感應器的裝置
只是加速計以下程式碼範例說明如何使用 getVendor()
和 getVersion()
方法執行以下作業
而負責任的 AI 技術做法
有助於達成這項目標在本範例中,我們正在尋找將 Google LLC 列為供應商並
的版本號碼為 3。如果裝置上沒有該感應器,我們會嘗試使用
加速計。
Kotlin
private lateinit var sensorManager: SensorManager private var mSensor: Sensor? = null ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) { val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY) // Use the version 3 gravity sensor. mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 } } if (mSensor == null) { // Use the accelerometer. mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } else { // Sorry, there are no accelerometers on your device. // You can't play this game. null } }
Java
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. } }
另一個實用的方法是 getMinDelay()
方法
,這會傳回感應器感測資料的最短時間間隔 (以微秒為單位)。任何感應器
這會為 getMinDelay()
傳回非零的值
是一種串流方式
感應器。串流感應器會定期感應資料,並在 Android 2.3 (API) 中推出
第 9 級)。如果呼叫 getMinDelay()
方法時感應器傳回 0,表示
感應器不是串流感應器,因為只有在
就能偵測出周遭動靜
getMinDelay()
方法非常實用
由您決定
感應器才能取得資料如果應用程式中的某些功能需要高資料
那麼你可以用這個方法判斷感應器
符合這些要求,並在應用程式內啟用或停用相關功能
。
注意:系統不會測量感應器的最大資料擷取率 也就是感應器架構將感應器資料傳送至應用程式的速度。 感應器架構會透過感應器事件回報資料,並有幾項因素會影響 應用程式接收感應器事件詳情請參閱「監控感應器事件」一文。
監控感應器事件
如要監控原始感應器資料,您必須實作兩種透過
SensorEventListener
介面:onAccuracyChanged()
和 onSensorChanged()
。Android 系統呼叫
這些方法發生的事件:
- 感應器的準確度變化。
在此情況下,系統會叫用
onAccuracyChanged()
方法,提供 並參照變更的Sensor
物件 感應器也更準確了準確度會以下列四個狀態常數表示:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, 或SENSOR_STATUS_UNRELIABLE
。 - 感應器會回報新值。
在此情況下,系統會叫用
onSensorChanged()
方法,為您提供SensorEvent
物件。SensorEvent
物件 內含新感應器資料的相關資訊,包括:資料準確度、 產生資料的感應器、產生資料的時間戳記, 例如感應器記錄到的資料
以下程式碼顯示如何使用 onSensorChanged()
方法監控
感應器。這個範例會顯示 TextView
中的原始感應器資料
是
在 main.xml 檔案中定義為 sensor_data
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
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); } }
在此範例中,叫用 registerListener()
方法時,會指定預設資料延遲時間 (SENSOR_DELAY_NORMAL
)。資料
延遲時間 (或取樣率) 會決定感應器事件傳送到應用程式的時間間隔
透過 onSensorChanged()
回呼方法傳送。預設
資料延遲適合監控
螢幕方向通常會變更,且會延遲 200,000 微秒。您可以指定
資料延遲,例如 SENSOR_DELAY_GAME
(20,000 微秒)
延遲時間)、SENSOR_DELAY_UI
(延遲 60,000 微秒) 或 SENSOR_DELAY_FASTEST
(0 微秒延遲時間)。從 Android 3.0 (API) 開始
等級 11) 也可以將延遲時間指定為絕對值 (以微秒為單位)。
您指定的延遲時間只是建議的延遲時間。Android 系統和其他應用程式 可能會改變這個延遲最佳做法是指定最大延遲時間 系統花費的時間通常比您指定的延遲時間還小 (也就是說,您應該選擇 但仍符合應用程式需求的最慢取樣率)。如果使用較長的延遲時間 處理器的負載較低 因此耗電量較低
沒有任何公開方法可判斷感應器架構傳送速率 感應器事件傳送至應用程式;不過,您可以使用與 感應器事件,以便計算多個事件的取樣率。您無需變更 設定完成後的取樣率 (延遲)。如果您因為某些原因而需要變更延遲 必須取消註冊感應器事件監聽器,再重新註冊。
另外請注意,本範例使用 onResume()
和
用於註冊及取消註冊感應器事件的 onPause()
回呼方法
接聽程式。最佳做法是一律停用不需要的感應器,
活動已暫停。如未執行這類動作,部分感應器會在幾小時內耗盡電池電力
有相當程度的電力,而且會快速消耗電池電力。系統
不會在螢幕關閉時自動停用感應器。
處理不同的感應器設定
Android 不會為裝置指定標準感應器設定, 也就是說,裝置製造商可在自家應用程式中加入任何感應器設定 Android 裝置。因此,裝置可能會納入多種 以因應各種設定 如果您的應用程式需要使用特定類型的感應器,請務必確認 才能順利執行應用程式
你可以透過以下兩種方式,確保裝置上有指定的感應器:
- 在執行階段偵測感應器,並視情況啟用或停用應用程式功能。
- 使用 Google Play 篩選器指定具有特定感應器設定的裝置。
我們會在以下章節中討論每個選項。
在執行階段偵測感應器
如果您的應用程式使用特定類型的感應器,但不需要,您可以使用 感應器架構,以便在執行階段偵測感應器,然後停用或啟用應用程式功能 。舉例來說,導航應用程式可能會使用溫度感應器 壓力感應器、GPS 感應器和地磁場感應器 (顯示溫度和氣溫) 壓力、位置和指南針方位。如果裝置沒有壓力感應器,您可以使用 感應器架構,以便在執行階段偵測壓力感應器,然後停用 部分顯示壓力的應用程式 UI 部分。舉例來說,以下程式碼會檢查 裝置上是否有壓力感應器:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) { // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Java
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 篩選器指定特定感應器設定
如果您是在 Google Play 發布應用程式,可以使用
資訊清單檔案中的 <uses-feature>
元素,藉此針對不支援的裝置篩選應用程式
請為您的應用程式
建立適當的感應器設定
<uses-feature>
元素包含多個硬體描述元,可讓您篩選
偵測應用程式是否含有特定感應器可列出的感應器包括:
加速計、氣壓計、指南針 (地磁場)、陀螺儀、光度和距離。
以下是資訊清單項目範例,可篩選沒有加速計的應用程式:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
如果將此元素和描述元新增至應用程式的資訊清單,使用者就會看到 才能顯示在 Google Play 上。
只有在您的應用程式出現時,您才應該將描述元設為 android:required="true"
完全仰賴特定感應器如果您的應用程式使用感應器的某些功能,
在沒有感應器的情況下仍執行,您應在 <uses-feature>
中列出感應器
但將描述元設為 android:required="false"
這可以確保
即使裝置沒有特定感應器,也可以安裝您的應用程式。這也是
專案管理的最佳做法,可協助您持續追蹤應用程式使用的功能。
請注意,如果應用程式使用特定感應器,但仍在沒有感應器的情況下執行,
則您應該在執行階段偵測感應器,並停用或啟用應用程式功能,
或適當。
感應器座標系統
一般來說,感應器架構會使用標準的 3 軸座標系統表示資料值。 對多數感應器來說,當裝置處於「裝置螢幕」時,座標系統是相對於裝置螢幕的定義 處於預設方向 (如圖 1 所示)。當裝置保持預設方向時, X 軸為水平,指向右側;Y 軸是垂直且指向上,Z 軸 指向螢幕外面。在這個系統中,畫面後方的座標 Z 的值為負數。下列感應器使用此座標系統:
最需要瞭解這個座標系統的關鍵點是,軸不會 當裝置的螢幕方向變更時 (也就是感應器的座標系統) 進行切換 不會隨著裝置移動而改變這個行為與 OpenGL 座標系統
另一個值得注意的是,應用程式不得假設裝置的自然 (預設) 螢幕方向為直向。許多平板電腦裝置的自然方向為橫向。且 感應器座標系統始終取決於裝置的自然方向。
最後,如果您的應用程式與感應器資料相符,您就必須使用
判斷螢幕旋轉的 getRotation()
方法,然後使用
要對應的 remapCoordinateSystem()
方法
感應器座標與螢幕座標。即使資訊清單指定
。
注意:部分感應器和方法使用的座標系統
相對於裝置的參考框架。這些
感應器和方法會傳回資料,代表與
Google 地球。詳情請參閱 getOrientation()
方法、getRotationMatrix()
方法、方向
感應器和旋轉向量
感應器。
感應器頻率限制
為了保護使用者的相關機密資訊 (如果應用程式鎖定 Android 12 (API 級別 31) 以上版本,系統會對重新整理作業設下限制 特定動作感應器和位置感應器提供的資料速率。這項資料 包含裝置網路所記錄的值 加速計 陀螺儀和 地理磁場 感應器。
重新整理頻率限制取決於您存取感應器資料的方式:
- 如果呼叫
registerListener()
敬上 監控感應器事件的方法,感應器取樣率為 只限 200 Hz。這點適用於registerListener()
方法。 - 如果您使用
SensorDirectChannel
類別, 感應器的取樣率僅限於RATE_NORMAL
, 通常約為 50 Hz
如果您的應用程式需要以更高的頻率收集動作感應器資料,您必須
宣告
HIGH_SAMPLING_RATE_SENSORS
敬上
權限,如以下程式碼片段所示。否則,如果您的應用程式
在不宣告這項權限的情況下,以更高的頻率收集動作感應器資料。
發生 SecurityException
。
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
存取和使用感應器的最佳做法
設計感應器時,請務必遵守下列規範: 本節這些指南是建議最佳做法,適用對象為所有使用感應器的使用者 存取感應器及取得感應器資料
只在前景收集感應器資料
在搭載 Android 9 (API 級別 28) 以上版本的裝置上,執行 背景具有下列限制:
基於這些限制,最佳做法是偵測 應用程式於前景運作或 前景服務。
取消註冊感應器事件監聽器
使用完感應器或感應器時,請務必取消註冊感應器的監聽器
活動暫停。如果已註冊感應器事件監聽器,並暫停其活動,感應器就會
會繼續取得資料並使用電池資源 (除非取消註冊感應器)。下列
程式碼顯示如何使用 onPause()
方法取消註冊事件監聽器:
Kotlin
private lateinit var sensorManager: SensorManager ... override fun onPause() { super.onPause() sensorManager.unregisterListener(this) }
Java
private SensorManager sensorManager; ... @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
詳情請參閱 unregisterListener(SensorEventListener)
。
使用 Android Emulator 進行測試
Android Emulator 提供一組虛擬感應器控制項 測試加速計、環境溫度、磁力儀 例如鄰近區域和亮度等等
模擬器與執行下列項目的 Android 裝置連線: SdkControllerSensor 應用程式。請注意,此應用程式僅適用於搭載 Android 4.0 (API) 的裝置 第 14 級) 或更高等級。(如果裝置執行的是 Android 4.0,必須具有 已安裝修訂版本 2)。SdkControllerSensor 應用程式會監控 並將裝置上的感應器傳輸到模擬器模擬器 再依據從感應器接收到的新值轉換 。
您可以在 SdkControllerSensor 應用程式查看原始碼 下列位置:
$ your-android-sdk-directory/tools/apps/SdkController
如要在裝置和模擬器之間轉移資料,請按照下列步驟操作: 步驟:
- 確認 USB 裝置已啟用偵錯功能。
- 使用 USB 傳輸線將裝置連接至您開發的機器上。
- 在裝置上啟動 SdkControllerSensor 應用程式。
- 在應用程式中選取要模擬的感應器。
執行下列
adb
指令:- 啟動模擬器。現在您應該可以將轉換套用至 移動裝置來啟動模擬器
$ adb forward tcp:1968 tcp:1968
注意: 如果對
實體裝置無法轉換模擬器,請嘗試執行
再次執行步驟 5 的 adb
指令。
詳情請參閱 Android 模擬器指南。
不要封鎖 onSensorChanged() 方法
感應器資料可能會頻繁變更,這表示系統可能會經常呼叫 onSensorChanged(SensorEvent)
方法。我們相信
應該盡量在 onSensorChanged(SensorEvent)
方法內執行,以免封鎖它。如果您的
應用程式要求您對資料進行篩選或減少感應器資料,
在 onSensorChanged(SensorEvent)
方法之外運作。
避免使用已淘汰的方法或感應器類型
許多方法和常數已淘汰。
尤其是 TYPE_ORIENTATION
已淘汰感應器類型。如要取得方向資料,請改用 getOrientation()
方法。同樣地,
已淘汰「TYPE_TEMPERATURE
」感應器類型。應使用
請改為在裝置上使用 TYPE_AMBIENT_TEMPERATURE
感應器類型
搭載 Android 4.0 系統
使用感應器前,請先驗證感應器
嘗試從裝置擷取資料前,請務必先確認裝置上是否存在感應器。錯誤做法 會假設感應器確實存在,因為這是常用的感應器。裝置製造商是 不需要在裝置上提供任何特定感應器。
謹慎選擇感應器延遲時間
使用 registerListener()
方法註冊感應器時,請務必選擇適合
或用途感應器能以極高速率提供資料。允許系統傳送
不必要的額外資料會消耗系統資源和電池電力