感應器總覽

大多數 Android 裝置都內建感應器,可測量動作、螢幕方向, 和各種環境條件這些感應器能夠提供高用量的原始資料 。如果您想監控 3D 裝置的移動或 或監控裝置附近的環境變化。舉例來說 遊戲可能會追蹤來自裝置重力感應器的讀數,藉此推斷複雜的使用者手勢 以及動作,例如傾斜、搖晃、旋轉或搖擺。同樣地,天氣應用程式可能會使用 裝置的溫度感應器和濕度感應器,用於計算並回報露點或旅遊 應用程式可能會使用地磁場感應器和加速計回報指南針 方針。

Android 平台支援以下三種感應器:

  • 動作感應器

    這些感應器會沿著三軸測量加速力和旋轉力,這個 類別包括加速計、重力感應器、陀螺儀和旋轉向量 感應器。

  • 環境感應器

    這些感應器會測量多種環境參數,例如環境氣溫 包括壓力、照明和濕度這個類別包括氣壓計、光量計 溫度計

  • 位置感應器

    這些感應器會測量裝置的實際位置,這個類別包括 螢幕方向感應器和磁力儀。

如要存取裝置上的感應器,並擷取原始感應器資料,請使用 Android 感應器架構感應器架構提供多種類別和介面,協助您執行更廣泛的 代表各式各樣的感應器工作舉例來說,您可以使用感應器架構執行以下操作:

  • 確認裝置可用的感應器。
  • 決定個別感應器的功能,例如最大範圍、製造商、功率 需求和解決方法
  • 取得原始感應器資料,並定義取得感應器資料的最低速率。
  • 註冊及取消註冊可監控感應器異動的感應器事件監聽器。

本主題將概略說明 Android 平台可用的感應器。 並介紹感應器架構。

感應器簡介

Android 感應器架構可讓你存取多種類型的感應器。其中一些感應器 有些則是以軟體為基礎硬體式感應器是實體元件 下載到手機或平板電腦裝置上。他們直接評估特定環境,藉此取得資料 ,例如加速度、地磁場強度或角度變化。軟體式 雖然感應器會模仿硬體感應器,但並非實體裝置。軟體式感應器 資料衍生自一或多個硬體式感應器,有時也稱為虛擬 感應器或合成感應器線性加速感應器和重力感應器是 軟體式感應器表 1 摘要列出 Android 支援的感應器 平台。

只有少數搭載 Android 系統的裝置搭載所有類型的感應器。例如大部分的手機裝置和 平板電腦具有加速計和磁力儀,但這些裝置擁有較少的裝置 氣壓計或溫度計此外,單一裝置可以有多個特定類型的感應器。適用對象 舉例來說,一部裝置可以有兩個重力感應器,每個感應器的重力範圍皆不同

表 1. 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 的前瞻相容性政策。

表 2. 各平台可用的感應器。

感應器 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_GYROSCOPETYPE_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 系統呼叫 這些方法發生的事件:

以下程式碼顯示如何使用 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 的值為負數。下列感應器使用此座標系統:

圖 1. 感應器使用的座標系統 (相對於裝置) 也能使用 Google Cloud CLI 或 Compute Engine API

最需要瞭解這個座標系統的關鍵點是,軸不會 當裝置的螢幕方向變更時 (也就是感應器的座標系統) 進行切換 不會隨著裝置移動而改變這個行為與 OpenGL 座標系統

另一個值得注意的是,應用程式不得假設裝置的自然 (預設) 螢幕方向為直向。許多平板電腦裝置的自然方向為橫向。且 感應器座標系統始終取決於裝置的自然方向。

最後,如果您的應用程式與感應器資料相符,您就必須使用 判斷螢幕旋轉的 getRotation() 方法,然後使用 要對應的 remapCoordinateSystem() 方法 感應器座標與螢幕座標。即使資訊清單指定 。

注意:部分感應器和方法使用的座標系統 相對於裝置的參考框架。這些 感應器和方法會傳回資料,代表與 Google 地球。詳情請參閱 getOrientation() 方法、getRotationMatrix() 方法、方向 感應器旋轉向量 感應器

感應器頻率限制

為了保護使用者的相關機密資訊 (如果應用程式鎖定 Android 12 (API 級別 31) 以上版本,系統會對重新整理作業設下限制 特定動作感應器和位置感應器提供的資料速率。這項資料 包含裝置網路所記錄的值 加速計 陀螺儀地理磁場 感應器

重新整理頻率限制取決於您存取感應器資料的方式:

如果您的應用程式需要以更高的頻率收集動作感應器資料,您必須 宣告 HIGH_SAMPLING_RATE_SENSORS敬上 權限,如以下程式碼片段所示。否則,如果您的應用程式 在不宣告這項權限的情況下,以更高的頻率收集動作感應器資料。 發生 SecurityException

AndroidManifest.xml

<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

如要在裝置和模擬器之間轉移資料,請按照下列步驟���作: 步驟:

  1. 確認 USB 裝置已啟用偵錯功能。
  2. 使用 USB 傳輸線將裝置連接至您開發的機器上。
  3. 在裝置上啟動 SdkControllerSensor 應用程式。
  4. 在應用程式中選取要模擬的感應器。
  5. ���行���列 adb ���令:

  6. $ adb forward tcp:1968 tcp:1968
    
  7. 啟動模擬器。現在您應該可以將轉換套用至 移動裝置來啟動模擬器

注意: 如果對 實體裝置無法轉換模擬器,請嘗試執行 再次執行步驟 5 的 adb 指令。

詳情請參閱 Android 模擬器指南

不要封鎖 onSensorChanged() 方法

感應器資料可能會頻繁變更,這表示系統可能會經常呼叫 onSensorChanged(SensorEvent) 方法。我們相信 應該盡量在 onSensorChanged(SensorEvent) 方法內執行,以免封鎖它。如果您的 應用程式要求您對資料進行篩選或減少感應器資料, 在 onSensorChanged(SensorEvent) 方法之外運作。

避免使用已淘汰的方法或感應器類型

許多方法和常數已淘汰。 尤其是 TYPE_ORIENTATION 已淘汰感應器類型。如要取得方向資料,請改用 getOrientation() 方法。同樣地, 已淘汰「TYPE_TEMPERATURE」感應器類型。應使用 請改為在裝置上使用 TYPE_AMBIENT_TEMPERATURE 感應器類型 搭載 Android 4.0 系統

使用感應器前,請先驗證感應器

嘗試從裝置擷取資料前,請務必先確認裝置上是否存在感應器。錯誤做法 會假設感應器確實存在,因為這是常用的感應器。裝置製造商是 不需要在裝置上提供任何特定感應器。

謹慎選擇感應器延遲時間

使用 registerListener() 方法註冊感應器時,請務必選擇適合 或用途感應器能以極高速率提供資料。允許系統傳送 不必要的額外資料會消耗系統資源和電池電力