センサーの概要

ほとんどの Android デバイスには、動き、向き、 さまざまな環境条件下で使用してください。これらのセンサーは、非常に高い精度で元データを 精度が高く、デバイスの 3 次元の動きや、 デバイスの周囲の環境の変化を監視したい場合などです。たとえば、 デバイスの重力センサーの測定値を追跡して、複雑なユーザー ジェスチャーを推測する 傾斜、シェイク、回転、スイングなどの動きを追跡できます。同様に、天気情報アプリでは、 デバイスの温度センサーと湿度センサー アプリケーションでは、地磁気センサーと加速度計を使用してコンパスを報告します。 bearing

以下の関連リソースもご覧ください。

Android プラットフォームは、大きく分けて次の 3 つのカテゴリのセンサーをサポートしています。

  • モーション センサー

    3 軸方向の加速力や回転力を測定するためのセンサーです。この 加速度計、重力センサー、ジャイロスコープ、回転ベクトルが含まれます センサー。

  • 環境センサー

    周囲の気温など、さまざまな環境パラメータを測定します 気圧、照明、湿度などですこのカテゴリには、気圧計、光度計、 体温計。

  • 位置センサー

    デバイスの物理的な位置を測定するためのセンサーです。このカテゴリに含まれるもの 方向センサーや磁力計です

デバイスで使用可能なセンサーにアクセスし、生のセンサーデータを取得できます。 構成できますセンサー フレームワークには、幅広い処理の実行に役立つ複数のクラスとインターフェースが用意されています。 センサー関連のさまざまなタスクを実行できます。たとえば、このセンサー フレームワークを使用して次のことを行えます。

  • そのデバイスで使用できるセンサーを特定する。
  • 個々のセンサーの機能(最大範囲、メーカー、電力など)を判断する 要件、解決策です
  • センサーから測定データを取得する。また、測定データを取得する際の最低速度を定義する。
  • センサーの変化をモニタリングするセンサー イベント リスナーの登録や登録解除を行う。

このトピックでは、Android プラットフォームで使用可能なセンサーの概要について説明します。 また、Android センサー フレームワークの概要についても説明します。

センサーの概要

Android センサー フレームワークでは、さまざまなタイプのセンサーを利用できます。これらのセンサーの一部は ソフトウェアベースのものもあります。ハードウェアベース センサーは、物理コンポーネントとして構築されている スマートフォンやタブレット デバイスに変換できます。特定の環境を直接測定してデータを導き出します。 特性(加速度、地磁場の強さ、角の変化など)を表します。ソフトウェアベース ハードウェア ベースのセンサーに似ていますが、物理デバイスではありません。ソフトウェアベースのセンサー ハードウェア ベースのセンサーからデータを抽出して、 センサーや合成センサーなどです直線加速度センサーや重力センサーは、 ソフトウェアベースのセンサーです。表 1 に、Android でサポートされているセンサーの概要を示します。 説明します。

すべてのタイプのセンサーを備えた Android 搭載デバイスはまれにしかありません。たとえば、ほとんどのスマートフォン デバイスや タブレットには加速度計と磁力計が搭載されていますが、 気圧計や温度計を使ってみましょう。また、1 つのデバイスに同じタイプのセンサーが複数搭載されていることもあります。対象 たとえば、1 つのデバイスに 2 つの重力センサーがあり、それぞれが異なる範囲を持つことができます。

表 1. Android プラットフォームでサポートされているセンサータイプ

センサー 種類 説明 一般的な活用法
TYPE_ACCELEROMETER ハードウェア デバイスにかかる加速度(m/s2)を測定 重力を含む 3 つの物理軸(x、y、z)すべてを表す指標です。 動きの検出(シェイク、ティルトなど)。
TYPE_AMBIENT_TEMPERATURE ハードウェア 周囲の室温を摂氏(°C)単位で測定します。下記の注をご覧ください。 気温のモニタリング。
TYPE_GRAVITY ソフトウェアまたはハードウェア デバイスにかかる重力を m/s2 単位で測定します。 3 つの物理軸(x、y、z)で表します。 動きの検出(シェイク、ティルトなど)。
TYPE_GYROSCOPE ハードウェア 3 つのデバイスの回転速度をそれぞれ rad/s 単位で測定します 物理軸 (x、y、z)です。 回転の検出(スピン、ターンなど)。
TYPE_LIGHT ハードウェア 周囲光レベル(照度)をルクス単位で測定します。 画面の明るさの制御。
TYPE_LINEAR_ACCELERATION ソフトウェアまたはハードウェア 衝突した加速度(m/s2)を 適用されたデバイスの数: 重力を除く 3 つの物理軸(x、y、z)すべてに対して測定されます。 1 軸方向の加速度のモニタリング。
TYPE_MAGNETIC_FIELD ハードウェア 地球の 3 つの物理軸(x、y、z)の周囲地磁気を測定 μT。 コンパスの作成。
TYPE_ORIENTATION ソフトウェア 3 つの物理軸(x、y、z)すべてに対するデバイスの回転角度を測定します。 API レベル 3 以降では、次の要素の傾き行列と回転行列を取得できます。 重力センサーと地磁場センサーを getRotationMatrix() メソッドを呼び出します。 デバイスの姿勢の特定。
TYPE_PRESSURE ハードウェア 周囲の気圧をヘクトパスカル(ミリバール)単位で測定します。 気圧変化のモニタリング。
TYPE_PROXIMITY ハードウェア 対象物のビュー画面に対する物体の近さを cm 単位で測定します ダウンロードしますこのセンサーは通常、ハンドセットが 向上します 通話中のスマートフォンの位置。
TYPE_RELATIVE_HUMIDITY ハードウェア 周囲の相対湿度を百分率(%)で測定します。 露点温度、絶対湿度、相対湿度のモニタリング。
TYPE_ROTATION_VECTOR ソフトウェアまたはハードウェア デバイスの向きを測定するには、デバイスの向きを ベクトルを指定します。 動きの検出と回転の検出。
TYPE_TEMPERATURE ハードウェア デバイスの温度を摂氏(°C)単位で測定します。このセンサー 実装はデバイスやそれに合わせて このセンサーは TYPE_AMBIENT_TEMPERATURE センサーに置き換わりました。 API レベル 14 温度のモニタリング。

センサー フレームワーク

これらのセンサーにアクセスし、Android センサー フレームワークを使用してセンサーの未加工データを取得できます。 センサー フレームワークは android.hardware パッケージの一部であり、以下が含まれています。 クラスとインターフェース:

SensorManager
このクラスを使用して、センサー サービスのインスタンスを作成できます。このクラスは、 センサーへのアクセスと一覧表示、センサー イベントの登録と登録解除を行うさまざまなメソッド 画面の向き情報の取得などに使用されます。このクラスには、いくつかのセンサー定数も用意されています。 センサーの精度の報告、データ取得率の設定、センサーの調整に使用されます。
Sensor
このクラスを使用して、特定のセンサーのインスタンスを作成できます。このクラスには、 センサーの機能を判断するためのメソッドも用意しています。
SensorEvent
システムはこのクラスを使用して、センサー イベント オブジェクトを作成します。このオブジェクトは、 トリガーされます。センサー イベント オブジェクトには、センサーの元データ、 イベントを生成したセンサーのタイプ、データの精度、イベントのタイムスタンプ
SensorEventListener
このインターフェースを使用して、通知を受け取る 2 つのコールバック メソッド(センサー イベント)をトリガーできます。

通常のアプリでは、上記のセンサー関連 API を使用して、次の 2 つの基本的なタスクを行います。

  • センサーとセンサー機能の特定

    実行時にセンサーやセンサー機能を特定すると、アプリに センサーのタイプや機能に依存する機能が必要になります。たとえば デバイスに搭載されているすべてのセンサーを特定し、アプリの機能を無効にする 開発できます同様に、すべてのセンサーを識別して、 最適なパフォーマンスのセンサー実装を選択できるように、 説明します

  • センサー イベントをモニタリングする

    センサーから測定データを取得するには、センサー イベントをモニタリングします。センサー イベントは毎回発生 センサーが測定中のパラメータの変化を検出したときセンサー イベントによって、 イベントをトリガーしたセンサーの名前 イベントのタイムスタンプ、イベントの精度、トリガーされた生のセンサーデータ 追加できます。

センサー対応状況

センサーが利用できるかどうかはデバイスによって異なりますが、Android によっても異なります。 あります。これは、Android センサーが数々の過程で導入され、 プラットフォーム リリースです。たとえば、Android 1.5(API レベル 3)で多くのセンサーが導入されましたが、 は実装されず、Android 2.3(API レベル 9)までは使用できませんでした。同様に 複数のセンサーが Android 2.3(API レベル 9)と Android 4.0(API レベル 14)で導入されました。2 本 センサーのサポートは終了し、より優れた新しいセンサーに置き換えられました。

表 2 に、プラットフォームごとのセンサー対応状況をまとめます。たった 4 センサーの変更を伴うプラットフォームであるため、ここに挙げています。センサーは 非推奨と表示されていても、後続のプラットフォームで使用できます(ただし、 センサーが存在するデバイス)に関する記述が、Android の上位互換性ポリシーに準拠しています。

表 2. プラットフォームごとのセンサー対応状況

センサー Android 4.0
(API Level 14)
Android 2.3
(API Level 9)
Android 2.2
(API Level 8)
Android 1.5
(API Level 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 には、状態ファイルのタイプを (最大範囲、解像度、消費電力など)が 提供します。

デバイスに搭載されているセンサーを特定するには、まずセンサーへの参照を取得する必要があります あります。そのためには、次の手順で 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_ALLTYPE_GYROSCOPE など) TYPE_LINEAR_ACCELERATION、または TYPE_GRAVITY

また、getDefaultSensor() メソッドを使用してタイプを渡すことで、デバイスに特定の種類のセンサーが存在するかどうかを判断することもできます。 定数を指定します。デバイスに特定のタイプのセンサーが複数ある場合は、 センサーはデフォルトのセンサーとして指定する必要があります。特定の環境にデフォルトのセンサーが存在しない場合 タイプのセンサーの場合、メソッド呼び出しは null を返します。つまり、デバイスにそのタイプのセンサーは搭載されていません。 センサー。たとえば、次のコードでは、デバイス上に磁力計があるかどうかを確認しています。

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() メソッド。

次の 2 つのパブリック メソッドが特に役立つのは、 センサーのバージョンも異なります。たとえば、アプリケーションで 傾斜やシェイクなどのユーザー ジェスチャーをモニタリングする必要がある場合は、データ フィルタリング セットを 1 つ作成できます。 特定のベンダーの重力センサーを搭載した新しいデバイス向けのルールと最適化や、 重力センサーがなく重力センサーがなく、 加速度計のみが必要です次のコードサンプルは、getVendor() メソッドと getVersion() メソッドを使用して、以下を行う方法を示しています。 できます。このサンプルでは、ベンダーとして 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.
    }
}

もう 1 つの便利なメソッドは getMinDelay() メソッドです。 センサーがデータを検知するために使用できる最小時間間隔(マイクロ秒単位)を返します。すべてのセンサー getMinDelay() に対してゼロ以外の値を返す もう一つはストリーミングです。 センサー。ストリーミング センサーは定期的にデータを検知する機能であり、Android 2.3(API)で導入されました。 レベル 9)。getMinDelay() メソッドを呼び出したときにセンサーがゼロを返した場合は、 センサーは、データに変化があったときにのみデータをレポートするため、ストリーミング センサーではありません。 パラメータを指定します。

getMinDelay() メソッドを使用すると、 これに加えて センサーがデータを取得できますアプリの特定の機能で大量のデータが必要な場合 ストリーミング センサーの場合、この方法を使用して、センサーが これらの要件を満たしたうえで、アプリケーションの関連する機能を有効または無効にできます。 必要があります。

注意: センサーの最大データ取得速度は、 センサー・フレームワークがセンサー・データをアプリケーションに配信する速度が必要です。「 センサー フレームワークは、センサー イベントを通じてデータを報告します。また、いくつかの要因がセンサー イベントを通じてデータを報告します。 センサーイベントを受信します。詳細については、センサー イベントのモニタリングをご覧ください。

センサー イベントのモニタリング

センサーの未加工データをモニタリングするには、 SensorEventListener インターフェース: onAccuracyChanged()onSensorChanged()。Android システムは これらのメソッドを使用する必要があります。

  • センサーの精度が変化する。

    この場合、システムは onAccuracyChanged() メソッドを呼び出し、 変更された Sensor オブジェクトへの参照と、 センサーの新たな精度です精度は、次の 4 つのステータス定数のいずれかで表されます。 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);
    }
}

この例では、デフォルトのデータ遅延(SENSOR_DELAY_NORMAL)を、registerListener() メソッドが呼び出されたときに指定しています。データ 遅延(サンプリング レート)は、センサー イベントがアプリケーションに送信される間隔を制御します。 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 デバイス。そのため、デバイスにはさまざまな 幅広い構成のセンサーを提供しています。 アプリが特定の種類のセンサーに依存している場合は、そのセンサーが センサーがデバイスに存在することので、アプリを正常に実行できます。

デバイスに特定のセンサーが存在することを確認するには、次の 2 つの方法があります。

  • ランタイムにセンサーを検出し、その結果に応じてアプリの機能を有効または無効にする。
  • 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. センサーで使用される座標系(デバイスを基準とする) API

この座標系を理解するうえで最も重要な点は、軸は デバイスの画面の向き(センサーの座標系)が変更されたときにスワップされます。 デバイスが変わっても変化しません。この動作は OpenGL の動作と同じです。 座標系です。

理解しておくべきもう一つのポイントは、アプリは、デバイスの正常な動作を前提としないことです。 (デフォルト)向きは縦向きです。多くのタブレット デバイスでは、自然な向きは横向きになっています。そして センサー座標系は、常にデバイスの自然な向きに基づいています。

最後に、アプリでセンサーデータを画面上のディスプレイと一致させる場合は、 getRotation() メソッドを使用して画面の回転を判断してから、 マッピングする remapCoordinateSystem() メソッド 画面座標に変換できますこれは、マニフェストで 縦向きのみのディスプレイです。

注: 一部のセンサーやメソッドでは、 (デバイスの参照フレームではなく)世界の参照フレームを基準とします。これらの センサーやメソッドは、デバイスの動きや、デバイスの位置を 表示されます。詳しくは、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 には、仮想センサー コントロールのセットが用意されており、 加速度計、周囲温度、磁力計、 近接、光などを遮断します。

エミュレータは、 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. SdkControllerSensor アプリで、エミュレートするセンサーを選択します。
  5. 次の adb コマンドを実行します。

  6. $ adb forward tcp:1968 tcp:1968
    
  7. Android Emulator を起動します。ここまでで、作成したテーブルに エミュレータを使用できます。

注: エミュレータが変換されない場合は、次のコマンドを実行し、 adb コマンドを再度実行します。

詳細については、Android エミュレータ ガイドをご覧ください。

onSensorChanged() メソッドをブロックしない

センサーデータは高速に変化する可能性があります。つまり、システムによって onSensorChanged(SensorEvent) メソッドが頻繁に呼び出される可能性があります。ベストプラクティスとして onSensorChanged(SensorEvent) メソッド内で実行する処理をできる限り少なくして、ブロックされないようにします。お使いの センサーデータのフィルタリングや縮小を行う必要がある場合は、 onSensorChanged(SensorEvent) メソッドの外部で機能します。

サポートが終了したメソッドやセンサータイプを使用しない

いくつかのメソッドと定数のサポートが終了しました。 特に、TYPE_ORIENTATION センサータイプのサポートが終了しました。向きのデータを取得するには、代わりに getOrientation() メソッドを使用します。同様に TYPE_TEMPERATURE センサータイプのサポートが終了しました。使用すべき デバイスの TYPE_AMBIENT_TEMPERATURE センサータイプ 実装することもできます

センサーを使用する前に確認する

センサーからデータを取得しようとする前に、必ずそのセンサーがデバイス上に存在することを確認します。すべきでないこと センサーが頻繁に使用されるという理由だけで、センサーが存在することを前提とします。デバイス メーカーは デバイスに特定のセンサーを用意する必要はありません。

センサーの遅延は慎重に選択する

registerListener() メソッドでセンサーを登録する場合は、 理解することが重要です。センサーからは、極めて高速にデータが提供される可能性があります。システムによる送信を許可する 不要なデータを増やすとシステム リソースが浪費され、バッテリーも消費されます。