6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZOZOAdvent Calendar 2023

Day 22

Wear OSでExerciseClientを使用して自転車の走行情報を取得する

Last updated at Posted at 2023-12-22

はじめに

なんとなく思い立ったのでWear OSのアプリを作った。誰かの参考になれば良いので公開します。

環境

  • Wear OS 3 (Wear OS by Google)
  • SKAGEN Falster Gen6

要件

  • ユーザーはある自転車のライドにおける総走行距離、総消費カロリー、最高速度を取得できる

完成品

ExerciseClientの初期設定

ExerciseTypeを初期化

val exerciseClient: ExerciseClient = HealthServices.getClient(context).exerciseClient

端末で該当のDataTypeをサポートしているか確認する

val necessaryDataTypes = setOf(
    DataType.SPEED_STATS,
    DataType.CALORIES_TOTAL,
    DataType.PACE_STATS,
    DataType.DISTANCE_TOTAL,
)

 // 引数にExerciseClientと↑のnecessaryDataTypesを渡す 
suspend fun isAllNecessaryDataTypesAvailable(
    exerciseClient: ExerciseClient,
    necessaryDataTypes: Set<DataType<*, *>>
): Boolean {
    val capabilities = exerciseClient.getCapabilitiesAsync().awaitWithException().getExerciseTypeCapabilities(ExerciseType.BIKING)
    return necessaryDataTypes.all { it in capabilities.supportedDataTypes }
}

端末で自転車の走行情報の計測が対応しているか確認する

suspend fun isBikingSupported(exerciseClient: ExerciseClient): Boolean {
    val capabilities = exerciseClient.getCapabilitiesAsync().awaitWithException()
    return ExerciseType.BIKING in capabilities.supportedExerciseTypes
}

端末で別のエクササイズが進行していないか確認する

suspend fun existsNoOtherExerciseInProgress(exerciseClient: ExerciseClient): Boolean {
    val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().awaitWithException()
    return exerciseInfo.exerciseTrackedStatus == NO_EXERCISE_IN_PROGRESS
}

走行情報を取得するためのコールバックを設定する

private fun ExerciseClient.setExerciseUpdateCallback() {
        val callback = object : ExerciseUpdateCallback {
            override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
                val latestMetrics = update.latestMetrics
                latestMetrics.getData(DataType.DISTANCE_TOTAL)?.total?.let { distance ->
                    // こんな感じでそれぞれのDataType毎のデータを取得する
                }
            }

            override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
                // no-op
            }

            override fun onRegistered() {
                // no-op
            }

            override fun onRegistrationFailed(throwable: Throwable) {
                // 省略
            }

            override fun onAvailabilityChanged(
                dataType: DataType<*, *>,
                availability: Availability
            ) {
                // 省略
            }
        }
        this.setUpdateCallback(callback)
    }

アプリのPermission周りの設定

必要な権限は以下です。これらを適宜権限許諾リクエストをしてください。

詳しくはこちら

動作確認のためのadbコマンド

次は動作確認です。自転車で走り回るのも良いですが、adbコマンドで走行情報を送信することもできます。以下のような項目を組み合わせて任意の走行情報を作ることができます。単位など詳しくはこちらになります。

  • エクササイズの総時間
  • 心拍数
  • 平均速度
  • 既定のルートを使用して位置データを出力するかどうか
  • 最大標高変化率

それを踏まえて、走行速度10m/s、総時間3,600sの走行情報を作成すると、↓のようになります。

adb shell am broadcast \
-a "whs.synthetic.user.START_EXERCISE" \
--ei exercise_options_duration_secs 3600 \
--ef exercise_options_average_speed 10 \
com.google.android.wearable.healthservices

終わりに

今回の成果物はこちらのActivitySensorImpl辺りに載せてあります!興味ある方はこちらも合わせてどうぞ。

楽しいWear OS & サイクリングライフを!

参考文献

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?