Android センサープログラミング入門

概要

本書は、Android端末に搭載されたセンサーを活用したアプリケーション開発について解説する。現代のAndroid開発環境であるAndroid Studioと、推奨されるAPIであるCameraX、FusedLocationProviderClient、SensorManagerを用いて、カメラ、GPS、加速度センサーを活用した実践的なアプリケーション開発を学ぶ。

前提知識: Kotlinプログラミングの基礎、Android開発の基本概念


第1章 Android開発環境

1.1 Android Studio

Android Studioは、Googleが提供するAndroidアプリ開発の公式統合開発環境(IDE)である。IntelliJ IDEAをベースに構築されており、Androidアプリ開発に必要なすべてのツールを統合している。

主な特徴

機能説明
コード編集支援Kotlin、Java、C++に対応したコード補完と構文チェック
ビジュアルレイアウトエディタドラッグ&ドロップでUI設計が可能
Android Emulator実機がなくても仮想デバイスでテスト可能
Gradleビルド自動化システム
Gemini統合AIによるコード生成・修正支援(最新版)

1.2 Android SDK

Android SDK(Software Development Kit)は、Androidアプリ開発に必要なライブラリ、ツール、APIを提供する。

主な構成物

構成物説明
Android API各バージョンのAndroid向けライブラリ
Android Virtual Device (AVD)エミュレータ。プログラムのテスト時に使用
ADB (Android Debug Bridge)Android機器との通信・ファイル転送ツール
SDK Platform-Toolsデバッグ用ツール群

1.3 開発環境のセットアップ

Android Studioのインストール手順は以下の通りである。

  1. Android Studio のダウンロード: developer.android.com/studio から最新版をダウンロード
  2. インストールの実行: ウィザードに従いインストール(SDK、エミュレータも同時にインストール可能)
  3. 初期設定: 初回起動時にSDKコンポーネントが自動的にダウンロードされる
  4. エミュレータの作成: AVD Managerから仮想デバイスを作成

第2章 Androidプロジェクトの基礎

2.1 プロジェクト構成

Androidプロジェクトは、以下のディレクトリ構造で構成される。

ディレクトリ・ファイル役割
app/src/main/java/ または kotlin/Kotlinソースコード
app/src/main/res/layout/画面レイアウトのXMLファイル
app/src/main/AndroidManifest.xmlアプリの設定、権限の宣言
app/build.gradle.kts依存関係とビルド設定

2.2 アクティビティ

アクティビティ(Activity) とは、Androidアプリの画面を構成する基本要素である。ユーザーインターフェースを提供し、ユーザーとの対話を処理する。各アクティビティはライフサイクルを持ち、onCreate()onResume()onPause()などのコールバックメソッドで状態遷移を管理する。

2.3 権限の設定

センサーやカメラなどのハードウェア機能を使用するには、AndroidManifest.xmlに権限を宣言する必要がある。Android 6.0以降では、危険な権限(カメラ、位置情報など)は実行時にユーザーの許可を求める必要がある。

<!-- カメラ使用権限 -->
<uses-permission android:name="android.permission.CAMERA" />

<!-- 位置情報使用権限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

第3章 Android端末のセンサー

3.1 センサーの種類

Android端末には、様々なセンサーが搭載されている。

モーションセンサー

センサー測定内容用途
加速度センサーX、Y、Z軸方向の加速度端末の動き、傾き、シェイク検出
ジャイロセンサーX、Y、Z軸周りの回転速度端末の向き、回転運動の検出
重力センサー重力加速度の方向と大きさ端末の傾き検出

位置センサー

センサー測定内容用途
磁気センサー地磁気の強さと方向コンパス、方位検出
GPSレシーバGPS衛星からの信号現在位置の測位

環境センサー

センサー測定内容用途
照度センサー周囲の明るさ画面輝度の自動調整
気圧センサー大気圧高度測定、天気予測

3.2 センサーへのアクセス

Androidでセンサーにアクセスするには、SensorManagerクラスを使用する。

// SensorManagerの取得
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

// 加速度センサーの取得
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

3.3 端末の局所座標系

センサーの計測値は、端末の局所座標系で表される。座標系は端末のデフォルトの向き(多くのスマートフォンでは縦向き)を基準に定義される。

重要: 画面の向きが変わっても、センサーの座標系は変化しない。これはOpenGLの座標系と同じ振る舞いである。

端末を机の上に水平に置いた場合、重力加速度(約9.8 m/s²)はZ軸方向に作用する。端末を縦に立てると、重力加速度はY軸方向に作用する。


第4章 カメラアプリの開発(CameraX)

4.1 CameraXの概要

CameraXは、Androidでカメラ機能を実装するための推奨ライブラリである。Jetpackの一部として提供され、以下の特徴を持つ。

注意: 旧Camera API(android.hardware.Camera)は非推奨である。新規開発ではCameraXまたはCamera2を使用すること。

4.2 依存関係の追加

build.gradle.ktsに以下の依存関係を追加する。

val cameraxVersion = "1.5.0"
implementation("androidx.camera:camera-camera2:$cameraxVersion")
implementation("androidx.camera:camera-lifecycle:$cameraxVersion")
implementation("androidx.camera:camera-view:$cameraxVersion")

4.3 権限の設定

AndroidManifest.xmlにカメラ権限を追加する。

<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />

android.hardware.camera.anyを指定すると、前面カメラまたは背面カメラのいずれかが搭載されている端末でアプリが動作する。

4.4 カメラプレビューの実装

CameraXでは、ProcessCameraProviderを使用してカメラをライフサイクルにバインドする。

class MainActivity : AppCompatActivity() {
    private lateinit var previewView: PreviewView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        previewView = findViewById(R.id.previewView)
        startCamera()
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()

            // プレビューの設定
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(previewView.surfaceProvider)
            }

            // 使用するカメラの選択(背面カメラ)
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            // カメラをライフサイクルにバインド
            cameraProvider.unbindAll()
            cameraProvider.bindToLifecycle(this, cameraSelector, preview)

        }, ContextCompat.getMainExecutor(this))
    }
}

前面カメラを使用する場合は、CameraSelector.DEFAULT_FRONT_CAMERAを指定する。

4.5 CameraXのユースケース

CameraXは以下の4つのユースケースを提供する。

ユースケース説明
Previewカメラ映像のリアルタイム表示
ImageCapture静止画の撮影と保存
VideoCapture動画の録画
ImageAnalysisフレームごとの画像解析(機械学習など)

第5章 位置情報アプリの開発

5.1 Fused Location Providerの概要

Fused Location Provider(FLP)は、Google Play Servicesが提供する位置情報取得APIである。GPS、Wi-Fi、モバイルネットワークを組み合わせて、効率的かつ正確な位置情報を提供する。

FusedLocationProviderClientは、位置情報にアクセスするためのメインエントリーポイントである。

5.2 依存関係の追加

build.gradle.ktsに以下の依存関係を追加する。

implementation("com.google.android.gms:play-services-location:21.3.0")

5.3 権限の設定

AndroidManifest.xmlに位置情報権限を追加する。

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
権限精度説明
ACCESS_FINE_LOCATION高精度GPS、Wi-Fi、モバイルネットワークを使用
ACCESS_COARSE_LOCATION低精度Wi-Fi、モバイルネットワークのみ使用(都市レベル)

5.4 位置情報の取得

class MainActivity : AppCompatActivity() {
    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    }

    private fun requestLocationUpdates() {
        val locationRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY,
            2000L  // 更新間隔(ミリ秒)
        ).build()

        val locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                for (location in locationResult.locations) {
                    val latitude = location.latitude   // 緯度
                    val longitude = location.longitude // 経度
                    // 位置情報を使用した処理
                }
            }
        }

        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }
}

5.5 取得できるデータ

プロパティ説明
latitude緯度(度)
longitude経度(度)
altitude高度(メートル)
accuracy精度(メートル)
time測位時刻(1970年1月1日からのミリ秒)

第6章 加速度センサーによるデータ計測

6.1 加速度センサーの実装

加速度センサーのデータを取得するには、SensorEventListenerインターフェースを実装する。

class MainActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onResume() {
        super.onResume()
        accelerometer?.let {
            sensorManager.registerListener(
                this,
                it,
                SensorManager.SENSOR_DELAY_NORMAL
            )
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }

    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            val x = event.values[0]  // X軸加速度 [m/s²]
            val y = event.values[1]  // Y軸加速度 [m/s²]
            val z = event.values[2]  // Z軸加速度 [m/s²]
            // センサーデータを使用した処理
        }
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // 精度変更時の処理
    }
}

6.2 サンプリングレート

registerListenerの第3引数でサンプリングレートを指定する。

定数説明用途
SENSOR_DELAY_NORMAL通常速度(約200ms)画面回転検出
SENSOR_DELAY_UIUI向け(約60ms)ゲームUI
SENSOR_DELAY_GAMEゲーム向け(約20ms)ゲーム
SENSOR_DELAY_FASTEST最速高精度計測

6.3 計測結果の解釈

端末を水平に置いた場合

Z軸方向に約9.8 m/s²(1G)の加速度が検出される。これは重力加速度がZ軸方向に作用しているためである。

端末を縦に立てた場合

Y軸方向に約9.8 m/s²の加速度が検出される。重力加速度の方向が変化したことを反映している。

6.4 歩行データの計測実験

加速度センサーを用いた歩行データ計測の実験例を示す。

実験条件

項目内容
使用機材Android端末の加速度センサー
サンプリング周期200回/秒

実験手順(3通り)

条件計測時間
左後ポケットに入れて歩行約460秒
右手に持って歩行約100秒
左手に持って歩行約100秒

計測データの形式

内容
A列機体番号(例: 015d49021)
B列タイムスタンプ
C列X軸加速度
D列Y軸加速度
E列Z軸加速度

加速度センサーを用いて歩行データを計測すると、周期的な加速度変化が観測される。計測条件(端末の保持位置など)によってデータの特徴が異なる。

保持位置データの特徴
手に持って歩行腕の振りによる周期的な変動
ポケットに入れて歩行体の上下動による変動パターン

6.5 3次元グラフによる可視化

3次元グラフ(X、Y、Z軸をプロット)で可視化すると、歩行パターンの特徴を把握できる。計測データの単位はm/s²である。グラフを回転させることで、様々な角度から分布の形状を確認できる。

左手に持った場合と右手に持った場合で、データ点の分布パターンに違いが見られる。これは、歩行時の腕の振りや端末の姿勢の違いを反映している。


第7章 センサー情報の技術仕様

7.1 一般的なセンサーチップの例

Android端末に搭載されるセンサーチップは、複数のセンサー機能を1チップに統合していることが多い。例えば、3軸ジャイロセンサーと3軸加速度センサーを1チップで実現する製品がある。

一般的な仕様例(モーションセンサー)

項目仕様
大きさ3〜5mm角程度
ジャイロセンサー計測範囲±250〜±2000°/sec(設定可能)
加速度センサー計測範囲±2g〜±16g(設定可能)

7.2 GPSレシーバ

GPSレシーバは、GPS衛星からの信号を受信し、現在位置の測位を行う。現代のスマートフォンでは、GPS、GLONASS、Galileo、BeiDouなど複数の衛星測位システムに対応していることが多い。


まとめ

本書では、Android Studioを用いた現代のAndroid開発環境で、カメラ、GPS、加速度センサーを活用したアプリケーション開発を解説した。

重要なポイント

  1. 開発環境: Android Studioが公式IDEであり、必要なツールがすべて統合されている
  2. カメラAPI: CameraXが推奨ライブラリであり、旧Camera APIは非推奨
  3. 位置情報API: FusedLocationProviderClientがGPSとネットワークを統合した効率的な位置情報を提供
  4. センサーAPI: SensorManagerを通じて各種センサーにアクセス可能
  5. 権限管理: センサーやカメラの使用には適切な権限の宣言と実行時許可が必要
  6. 座標系: X軸は右向きが正、Y軸は上向きが正、Z軸は画面から手前向きが正

Android端末には多様なセンサーが搭載されており、これらを活用することで位置情報の取得、動作の検出、カメラを用いた画像処理など、様々なアプリケーションを開発できる。


付録:歴史的背景

本書の内容は、2012年頃にGoogle Nexus 7タブレットとEclipse IDEを用いて作成された教材を基に、現代のAndroid開発環境に合わせて全面的に改訂したものである。

当時の開発環境と現在の比較は以下の通りである。

項目2012年頃現在(2024年以降)
IDEEclipse + ADTAndroid Studio
言語JavaKotlin(推奨)/ Java
カメラAPICamera APICameraX / Camera2
位置情報APILocationManagerFusedLocationProviderClient
ビルドシステムAntGradle

センサーの基本原理(座標系、加速度の計測など)は変わっていないが、APIとツールは大きく進化している。