kako.dev

開発、自作アプリのこと

ミリしら Health Connect

Google I/O '22 で発表があった「HealthConnect」をとりあえず触ってみたのでその所感を雑にまとめます。

ちゃんと理解したら、また別にブログ書きます。

HealthConnect

I/OのDeveloperKeynoteにあった発表をまとめるとこんな感じ(英語聞き取りミスで間違いあるかも)

  • Samsungとのコラボで生まれた新しいプラットフォーム
  • アプリ間の接続を簡素化して、少ない作業で多くのユーザーに簡単にアクセス可能
  • 権限を使用して、単一のAPIセットですべてのAndroidデバイスのヘルスデータに安全にアクセスして共有できる(マジか?!)
  • Sumsung Health, Fitbit, Google Fit はHealth Connectを採用している

Fitbit、Google FitはHealthConnect採用とあるが見てみてもよくわからなかった。

Alpha版公開中

Alpha版が公開されてるので触ってみた。

要件

minSdk 27以上であることを求められます。 Oreo 8.1以上です。きっついですね。

事前準備

HealthConnectのapkをインストールする必要があります。

play.google.com

https://developer.android.com/guide/health-and-fitness/health-connect/get-started

パーミッション

各データタイプに合わせて、読み取り・書き込みパーミッション許可する必要があります。

AndroidManifest.xml にパーミッションを渡します

<intent-filter>
            <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
        </intent-filter>
        <meta-data android:name="health_permissions"
                android:resource="@array/health_permissions" />

一例ですが、今回体温のデータでサンプルアプリ作ってみたので体温データの読み書きをしたい場合はこうです。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="health_permissions">
        <item>androidx.health.permission.BodyTemperature.READ</item>
        <item>androidx.health.permission.BodyTemperature.WRITE</item>
    </array>
</resources>

データタイプ

かなりたくさんあります。 ありとあらゆる情報をHealthConnectで管理できます。

androidx.health.connect.client.records  |  Android Developers

体温管理するサンプル作ってみた

HealthConnectClient生成

if (HealthConnectClient.isAvailable(context)) {
    val healthConnectClient = HealthConnectClient.getOrCreate(context)
}

パーミッション要求

パーミッションはCoroutineScope内で要求します

val requestPermissions = registerForActivityResult(HealthDataRequestPermissions()) { granted ->
       // success permission
}


fun checkPermissionsAndRun(requestPermissions: ActivityResultLauncher<Set<Permission>>) {
    lifecycleScope.launch {
        val granted = healthConnectClient.permissionController.getGrantedPermissions(PERMISSIONS)

       if (granted.containsAll(PERMISSIONS)) {
            // Permissions already granted
       } else {
            requestPermissions.launch(PERMISSIONS)
       }
    }
}

データ書き取り

体温データBodyTemperature をInsertします。 BodyTemperatureは引数に以下を取ります

  • temperatureDegreesCelsius: 摂氏温度
  • measurementLocation: 測った場所 脇や額、耳、手首などあらゆる検知方法に対応してます。非接触な方法までカバーしているのが今どき。 BodyTemperatureMeasurementLocation  |  Android Developers
  • time: 測った時間。Instant型です。
  • zoneOffset: TimeZone
  • metadata: メタデータ。パッケージネームやデバイス情報を送れます。ウェアラブルなども渡せるすごない。

メタデータでデバイス送れるのが最近の多種多様なデバイス環境をカバーしている印象受けますね。

suspend fun insertBodyTemperature(
        bodyTemperature: Double,
        onSuccess: (response: InsertRecordsResponse?) -> Unit,
        onFailed: (e: Throwable) -> Unit
    ) {
        val record = listOf(
            BodyTemperature(
                temperatureDegreesCelsius = bodyTemperature,
                measurementLocation = BodyTemperatureMeasurementLocation.ARMPIT,
                time = Instant.now(),
                zoneOffset = ZoneOffset.ofHours(9),
                metadata = Metadata(dataOrigin = DataOrigin(packageName = BuildConfig.APPLICATION_ID), device = Device(manufacturer = Build.MANUFACTURER, model = Build.MODEL, type = Build.TYPE))
            )
        )
    }

データ読み取り

ReadRecordsRequest を生成してデータを取得します。スキーマがデータごとではなく共通なところが楽。

  • recordType: 欲しいデータを指定します
  • timeRangeFilter: 取得する範囲を時間で指定します。あまりに膨大だとエラー吐きます。(Instant.MINとか)
  • pageSize: 取得件数
  • ascendingOrder: 並び順デフォルトがTrueなので、降順でほしいならfalseを指定します。
suspend fun getBodyTemperature(onSuccess: (response: ReadRecordsResponse<BodyTemperature>?) -> Unit, onFailed: (e: Throwable) -> Unit) {
        val request = ReadRecordsRequest(
            recordType = BodyTemperature::class,
            timeRangeFilter = TimeRangeFilter.Companion.after(Instant.now(Clock.systemDefaultZone()).minusSeconds(60 * 60 * 24)),
            pageSize = 30,
            ascendingOrder = false
        )
    }

こんな感じ

リポジトリ

github.com

所感

  • デバイス情報を送れるので、ウェアラブルやハードウェアなどのデータソースを渡せるのがよい
  • スマートウォッチなどのウェアラブルをつける要因の1つとして健康意識があるので、親和性高そう
  • 体重計や血圧計アプリなどでBluetooth経由で取得したデータをHealthConnectで管理するようなことできそう
  • 他のアプリから書き込まれた情報も取得できそうだけど、、どうなんだろう
  • 固有のアプリを超えた体験ができるといいなあ
  • 栄養とかまでインサートできて、本当にデータの種類が豊富
  • Android Oreo 8.1以上の要件はちょっときつい