Sensors API:その概要、センサーの種類、センサー操作

著者: IT Sectr 公開日: 2026-03-26 読了時間: 10 分

Sensors APIは、デバイスのハードウェアセンサーにアクセスするためのAndroidプラットフォームインターフェースです。APIは、加速度計、ジャイロスコープ、磁力計、光センサーなどのセンサーからデータを取得する統一された方法を提供します。Google、2026年によると、最新のAndroidデバイスの95%以上が少なくとも3種類のセンサーを搭載しており、コンテキスト認識型アプリケーション開発の幅広い可能性を開いています。

主要なポイント

  • Sensors API — デバイスのハードウェアセンサーを操作するための統合Androidインターフェース。
  • 3つのカテゴリ — Motion、Position、Environmentセンサー(それぞれ異なる測定原理)。
  • SensorManager — センサーリストの取得とリスナー登録のためのシステムサービス。
  • 更新レートはSENSOR_DELAY定数(NORMAL~FASTEST)で設定。
  • 仮想センサー — Gravity、Rotation Vector、Linear Accelerationは物理センサーの組み合わせに基づく。

AndroidにおけるSensors APIとは?

Sensors APIは、Android Frameworkのソフトウェアインターフェースであり、開発者にモバイルデバイスのハードウェアセンサーへのアクセスを提供します。APIはバージョン1.0からAndroid SDKの一部であり、android.hardwareパッケージから利用できます。このインターフェースは、Qualcomm、MediaTek、Samsung Exynosなどの異なるメーカーのセンサー実装間の違いを抽象化し、センサー操作の統一モデルを提供します。

Sensors APIの主な機能

APIは3つの主要な操作を可能にします:利用可能なセンサーのリスト取得、データ受信用リスナーの登録、更新レートの管理。SensorManagerはすべての操作の中心的なアクセスポイントとして機能します。システムはonSensorChangedコールバックを介してアプリケーションに通知し、float値の配列を持つSensorEventオブジェクトを渡します。

Sensors APIの進化

Androidの歴史を通じて、APIはいくつかの発展段階を経てきました。バージョン2.3(Gingerbread)ではバッチ処理(消費電力を抑えるためのセンサイベントのグループ化)が導入されました。Android 4.0(Ice Cream Sandwich)では仮想センサーのGravityとLinear Accelerationが追加されました。Android 8.0以降、システムはプライバシー強化のためセンサーへのバックグラウンドアクセスを制限しました。

kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
    Log.d("センサー", "${sensor.name} — ${sensor.type}")
}

制限と要件

すべてのデバイスが同じセンサーセットを備えているわけではありません。アプリケーションはリスナーを登録する前に、特定のセンサーの利用可能性を確認する必要があります。Androidエミュレータは限られたセンサーセット(加速度計と磁力計)のみをサポートします。他のセンサーのテストには物理デバイスが必要です。Android 12以降、アプリケーションはマニフェストでセンサーの使用を宣言する必要があります。

Androidセンサーの種類:Motion、Position、Environment

AndroidはすべてのセンサーをMotion、Position、Environmentの3つのカテゴリに分類します。Motionセンサーには加速度計、ジャイロスコープ、歩数計が含まれます。Positionセンサーには磁力計と方位が含まれます。Environmentセンサーには光、圧力、温度、湿度が含まれます。

カテゴリセンサータイプ(定数)物理/仮想
Motion加速度計TYPE_ACCELEROMETER物理
MotionジャイロスコープTYPE_GYROSCOPE物理
Motion歩数計TYPE_STEP_COUNTER物理
MotionGravityTYPE_GRAVITY仮想
Position磁力計TYPE_MAGNETIC_FIELD物理
PositionRotation VectorTYPE_ROTATION_VECTOR仮想
EnvironmentTYPE_LIGHT物理
Environment圧力TYPE_PRESSURE物理

Motionセンサー:加速度計とジャイロスコープ

加速度計は3軸(X、Y、Z)に沿ってm/s²単位で加速度を測定します。値には重力(静止時のZ軸方向で9.8 m/s²)が含まれます。ジャイロスコープは各軸周りのデバイスの回転速度である角速度をrad/s単位で測定します。これら2つのセンサーの組み合わせは、ナビゲーション、ゲーム、ARアプリケーションで使用されます。

kotlin
class SensorActivity : Activity(), SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]
            textView.text = "X: $x, Y: $y, Z: $z"
        }
    }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

Positionセンサー:磁力計と方位

磁力計(TYPE_MAGNETIC_FIELD)は3軸に沿って磁場をマイクロテスラ(µT)単位で測定します。デジタルコンパスとして使用され、加速度計と組み合わせてデバイスの方位角を決定します。Rotation Vectorは、ジャイロスコープ、加速度計、磁力計のデータを融合して正確な方位を決定する仮想センサーです。

Environmentセンサー:光、圧力、温度

光センサー(TYPE_LIGHT)は周囲光レベルをルクス(lx)単位で測定します。自動画面輝度調整に使用されます。圧力センサー(TYPE_PRESSURE)は気圧をヘクトパスカル(hPa)単位で測定し、ナビゲーションアプリケーションで海抜高度の決定に使用されます。

Sensors APIアーキテクチャの仕組み

Sensors APIはクライアント-サーバーアーキテクチャ上に構築されています。アプリケーションがクライアント、SensorManagerがAndroidシステムサービスとして機能します。アプリケーションがregisterListenerを介してリスナーを登録すると、SensorManagerはHAL(ハードウェア抽象化層)— Linuxカーネルレベルで動作する低レベルセンサードライバーと通信します。

センサイベントのライフサイクル

HALドライバーはハードウェアチップから生データを受信し、ノイズをフィルタリングして、スタックを上に—SensorService(システムプロセス)を経由してアプリケーションに渡します。データはfloat値の配列valuesとナノ秒単位のタイムスタンプを含むSensorEventオブジェクトとして渡されます。イベントレートは選択された配信モードに依存します。

イベント配信モード

リスナー登録時に、開発者は定数SENSOR_DELAY_NORMAL(200 ms)、SENSOR_DELAY_UI(60 ms)、SENSOR_DELAY_GAME(20 ms)、SENSOR_DELAY_FASTEST(0 ms — 最大レート)を使用してイベント間の希望する遅延を指定します。実際のレートは異なる場合があります—システムが消費電力を最適化します。

kotlin
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
    this,
    sensor,
    SensorManager.SENSOR_DELAY_GAME
)

バッチ処理

Android 2.3以降、センサーはバッチモードをサポートしています—イベントはFIFOバッファに蓄積され、1つのバッチで配信されます。これによりプロセッサはスリープモードをより長く維持でき、消費電力を最大60%削減します。バッファサイズはセンサーチップに依存し、Sensor.fifoMaxEventCountフィールドで指定されます。

SensorManagerを使用したセンサーアクセス

SensorManagergetSystemService(Context.SENSOR_SERVICE)を介して利用可能なシステムサービスです。センサーリストの取得、特定のデフォルトセンサーの取得、リスナーの登録/解除のメソッドを提供します。SensorManagerはシングルトンです—アプリケーション全体で1つのインスタンスです。

センサーの利用可能性の確認

センサーを使用する前に、その利用可能性を確認する必要があります。getDefaultSensor(type)メソッドは、センサーがデバイスに存在しない場合nullを返します。確認せずにnullを取得すると、リスナー登録時にNullPointerExceptionが発生します。getSensorList(type)メソッドはすべてのセンサーのリストを返します。

kotlin
fun checkSensorAvailability(type: Int): Boolean {
    val sensorManager =
        getSystemService(Context.SENSOR_SERVICE) as SensorManager
    return sensorManager.getDefaultSensor(type) != null
}

// 使用法:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
    Log.d("センサー", "ジャイロスコープ利用可能")
}

リスナーの登録と解除

リスナーはregisterListener(listener, sensor, delay)を介して登録されます。重要onPause()メソッドでunregisterListener(listener)を介してリスナーを解除する必要があります。これを行わないと、アプリケーションはバックグラウンドでもセンサイベントを受信し続け、バッテリーを消耗します。Android 8+は未解除のリスナーについてlogcatに警告を表示します。

精度変更の処理

onAccuracyChanged(sensor, accuracy)メソッドはセンサーの精度が変更されたときに呼び出されます。値:SENSOR_STATUS_ACCURACY_HIGH、MEDIUM、LOW、UNRELIABLE。UNRELIABLEを受信した場合、精度が回復するまでセンサーデータは無視されるべきです。例えば、磁力計はキャリブレーション(デバイスを8の字に振る)が必要です。

Kotlinでのセンサー操作コード例

Kotlinを使用したAndroidアプリケーションでのSensors APIの実用的な例を見てみましょう。最初の例 — 加速度計を使用した画面の向きの決定。2番目 — キャリブレーション付き磁力計データの読み取り。3番目 — 歩数計を使用した歩数検出。

デバイスの向きの決定

加速度計と磁力計の組み合わせを使用して向きを決定します。SensorManager.getRotationMatrix()メソッドは回転行列を計算し、getOrientation()はpitch、roll、azimuthの角度を抽出します。Azimuth(方位角) — ラジアン単位の磁北に対する角度。

kotlin
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)

SensorManager.getRotationMatrix(
    rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())

歩数計を使用した歩数検出

歩数計(TYPE_STEP_COUNTER)は、最後のデバイス再起動以降のユーザーの総歩数を返します。センサーはハードウェアレベルで動作し、アプリケーションが実行されていない場合でもアクティブです。セッションあたりの歩数を取得するには、初期値を保存し、差を計算する必要があります。

kotlin
var initialSteps = 0
var isInitialized = false

override fun onSensorChanged(event: SensorEvent) {
    if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
        if (!isInitialized) {
            initialSteps = event.values[0].toInt()
            isInitialized = true
        }
        val currentSteps = event.values[0].toInt()
        val sessionSteps = currentSteps - initialSteps
        Log.d("歩数", "セッションあたりの歩数: $sessionSteps")
    }
}

光センサーを使用した適応型明るさ

光センサーはインターフェースを環境条件に適応させることができます。低照度(10 lx未満)ではダークモードに切り替えられます。明るい日光(10000 lx超)ではコントラストを上げられます。ノイズフィルタリングには、最後の5値の移動平均が使用されます。

仮想センサーとフュージョンアルゴリズム

Androidは直接のハードウェア同等物を持たないいくつかの仮想センサーを提供します。仮想センサーは物理センサーの組み合わせに基づいて読み取り値を計算します。これにより開発者の負担が軽減されます—システム自体がデータフュージョンアルゴリズムを実装します。

GravityとLinear Acceleration

Gravity(TYPE_GRAVITY)センサーはローパスフィルターを使用して加速度計の読み取り値から重力成分を抽出します。Linear Acceleration(TYPE_LINEAR_ACCELERATION)は逆に重力を除去し、デバイスの線形加速度のみを残します。GravityとLinear Accelerationの合計は加速度計の生の読み取り値になります。

Rotation Vector

Rotation Vector — 最も複雑な仮想センサー。ジャイロスコープ(高周波変化)、加速度計(重力ベクトル)、磁力計(北に対する方位)からのデータを組み合わせます。結果は空間内のデバイスの絶対的な向きを記述するクォータニオンです。ARアプリケーションやVRヘッドセットで使用されます。

Game Rotation Vector

Game Rotation Vector — 磁力計を使用しないRotation Vectorの簡略版。方位精度は低くなりますが、更新レートと安定性が向上します。絶対的な北に対する方位よりも低遅延が重要なゲームに推奨されます。

センサー使用時のバッテリー最適化

センサーはデバイスで最も電力を消費するコンポーネントの一部です。加速度計とジャイロスコープを最大ポーリングレートで使用すると、3–4時間の連続動作でバッテリーを消耗させる可能性があります。センサー使用の最適化は、Sensors APIを使用するすべてのアプリケーションにとって重要なタスクです。

最適な遅延の選択

不必要にSENSOR_DELAY_FASTESTを使用しないでください。UIアニメーションにはSENSOR_DELAY_UI(60 ms)で十分です。画面の向きの検出にはSENSOR_DELAY_NORMAL(200 ms)で十分です。レートが高いほど、プロセッサはアクティブ状態でより多くの時間を費やします。NORMALとFASTESTの間では消費電力が最大10倍異なります。

バックグラウンドでのリスナー解除

Android 8.0(API 26)以降、バックグラウンドアプリケーションは低減されたレートでセンサイベントを受信します。Android 12+では、MotionおよびPositionセンサーへのバックグラウンドアクセスにBODY_SENSORS_BACKGROUND権限が必要です。アプリケーションがバックグラウンドに移行する際にリスナーを解除してください—これによりデバイスのバッテリー寿命が延びます。

バッチ処理とFIFOバッファ

registerListener(listener, sensor, delay, maxReportLatencyUs)メソッドを介してバッチ処理を使用します。maxReportLatencyUsパラメータはマイクロ秒単位の最大イベント配信遅延を設定します。1000000(1秒)の値では、イベントはセンサーのFIFOバッファに蓄積され、1秒に1回配信されます—プロセッサの起動頻度が低下します。

よくある質問

すべてのAndroidデバイスに存在するセンサーは?

最小セットは加速度計と磁力計です。これら2つのセンサーは95%以上のデバイスに搭載されています。ジャイロスコープ、光センサー、近接センサーは70–80%の最新モデルに搭載されています。その他のセンサー(圧力、温度、湿度、歩数計)はあまり一般的ではなく、デバイスの価格帯に依存します。

TYPE_ACCELEROMETERとTYPE_LINEAR_ACCELERATIONの違いは?

TYPE_ACCELEROMETERは重力を含む完全な加速度(9.8 m/s²)を返します。TYPE_LINEAR_ACCELERATIONは重力を除いた加速度、つまりデバイスの運動加速度のみを返します。デバイスが静止している場合、加速度計はZ軸に沿って9.8 m/s²を示しますが、Linear Accelerationは全軸で0を示します。

必要なセンサーがデバイスにあるか確認する方法は?

適切な定数とともにgetPackageManager().hasSystemFeature()を使用します:FEATURE_SENSOR_ACCELEROMETER、FEATURE_SENSOR_GYROSCOPE、FEATURE_SENSOR_PROXIMITYなど。別の方法として、getDefaultSensor(type)を呼び出し、結果がnullかどうかを確認します。初期化時の確認には最初の方法が推奨されます。

センサーの値が変動する理由と平滑化方法は?

センサーの生データにはノイズが含まれます。平滑化にはローパスフィルターを使用します:newValue = alpha * rawValue + (1 — alpha) * previousValue。alpha係数0.1–0.3は応答性と平滑性の良いバランスを提供します。ジャイロスコープにはゼロドリフト除去のためのハイパスフィルターも適用されます。

バックグラウンドでセンサーを使用できますか?

はい、ただし制限があります。Android 8.0以降、バックグラウンドアプリケーションのセンサイベントレートは低下します。Android 12以降、バックグラウンドでのセンサーアクセスにはBODY_SENSORS_BACKGROUND権限が必要です。バックグラウンド作業には、通知付きのForeground Serviceの使用が推奨されます。

まとめ

  • Sensors API — SensorManagerを介してデバイスのハードウェアセンサーからデータを取得する統合Androidインターフェース。
  • 3つのカテゴリ — Motion(加速度計、ジャイロスコープ)、Position(磁力計)、Environment(光、圧力)は異なる動作原理と用途を持つ。
  • 仮想センサー — Gravity、Linear Acceleration、Rotation Vectorは物理センサーのデータフュージョンに基づき、ハードウェア同等物を持たない。
  • 最適化 — 適切な遅延(SENSOR_DELAY_NORMAL、UI、GAME、FASTEST)の選択とバッチ処理の使用により消費電力を最大60%削減。
  • 制限 — Android 8+はバックグラウンドのセンサーレートを低減、Android 12+はバックグラウンドアクセスにBODY_SENSORS_BACKGROUNDが必要。
  • 基本確認 — リスナー登録前に、getDefaultSensorまたはhasSystemFeatureでセンサーの利用可能性を確認。
  • ノイズ平滑化にはローパスフィルターを使用し、バッテリー節約のためにバックグラウンド移行時にリスナーを解除。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください