LoginSignup
46
57

More than 5 years have passed since last update.

Google Fit API を使って、Androidで歩数を取得してみよう

Posted at

はじめに

私は、ヘルスケア事業部で、スマホの歩数計を活用したサービスの開発に携わっており、主にAndroidアプリ開発を行っております。

Androidでは、Google Fit API を使うことで、ヘルスケアに関する様々なデータを取得したり記録したりすることが出来ます。
その中でも歩数は、スマホ以外のデバイスや、ユーザーによる手動入力無しに計測/記録することができるため、モバイルアプリサービスに活用しやすいデータだと思います。
ということで今回は、Google Fit API を用いた歩数取得についてご紹介します。

Fit API での情報取得

FitAPIでは、ヘルスケアに関する様々なデータを取得することが出来ます。
まずはFitAPIでの、基本的な情報取得についてご紹介します。

1. 導入

FitAPIを導入するためにまずは、AndroidStudioにて必要なパッケージを導入したり、認証キーを手に入れたりする必要があります。
詳しくは、公式ガイドをご覧ください。

2. ユーザー許可を得る

情報取得を行うためには、GoogleFitの情報にアクセスするための許可を得る必要があります。
FitnessOptionsにてアクセスしたいDataTypeを指定し、権限をリクエストします。

val fitnessOptions = FitnessOptions.builder()
    .addDataType(DataType.TYPE_STEP_COUNT_DELTA)
    .addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
    .addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA)
    .build()

if (!GoogleSignIn.hasPermissions(
        GoogleSignIn.getLastSignedInAccount(this),
        fitnessOptions
    )
) {
    GoogleSignIn.requestPermissions(
        this,
        REQUEST_OAUTH_REQUEST_CODE,
        GoogleSignIn.getLastSignedInAccount(this),
        fitnessOptions
    )
} else {
    readData()
}

DataTypeの一覧は、こちらで見れます。
どのような情報が取得できるか分かるので、見てみると面白いです。

3. 情報を取得する

FitAPIの中には、BleApi/RecordingApi/GoalsApiなどなどありますが、情報取得に用いるのは HistoryApiになります。

timeRange(情報が欲しい期間)DataType(欲しい情報の種類)を指定してDataReadRequestを作成し、HistoryClientreadDataを呼び出してあげます。

val start = 1544540400000 // 2018-12-12 00:00:00
val end = Date().time

val request = DataReadRequest.Builder()
    .setTimeRange(start, end, TimeUnit.MILLISECONDS)
    .read(dataType)
    .build()

Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
    .readData(request)
    .addOnSuccessListener {
        // it: DataReadResponse
        Log.d("onSuccess", it.toString)
    }
}

Fit API を用いた歩数取得

FitAPIでの情報取得について、なんとなくイメージ持っていただけたかと思います。
つづいて、どのような歩数情報を得ることができるかをご紹介します。

歩数情報取得には複数パターンあるのですが、今回は以下の3つのDataTypeについて紹介します。

DataType.TYPE_STEP_COUNT_CUMULATIVE
DataType.TYPE_STEP_COUNT_DELTA
DataType.AGGREGATE_STEP_COUNT_DELTA

それぞれの取得方法と、実際にどのような値が取得できるかを紹介します。

TYPE_STEP_COUNT_CUMULATIVE

こちらは、端末起動時からの累積値が取得できるDataTypeです。

以下のようなコードで取得を行います。

val start = 1544540400000 // 2018-12-12 00:00:00
val end = Date().time // 現在時刻を指定

// 2018-12-12 00:00 ~ 現在時刻 の累積値を取得したい
val request = DataReadRequest.Builder()
    .setTimeRange(start, end, TimeUnit.MILLISECONDS)
    .read(DataType.TYPE_STEP_COUNT_CUMULATIVE)
    .build()

Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
    .readData(request)
    .addOnSuccessListener {

        // DataTypeを指定し、データセットを取得
        val dataSet = it.getDataSet(DataType.TYPE_STEP_COUNT_CUMULATIVE)

        // データセットの中のdataPointsの中に歩数情報リストが含まれてる
        dataSet.dataPoints.forEach { point ->

            // getStartTime/getEndTime でその情報がどの時間のものかが分かる
            val start = point.getStartTime(TimeUnit.MILLISECONDS)
            val end = point.getEndTime(TimeUnit.MILLISECONDS)

            // getValueの引数にField.FIELD_STEPSを指定することで、歩数値が取得できる
            val value = point.getValue(Field.FIELD_STEPS)
        }
    }

そうすると、以下のような情報が取得できました。

 start               end                 value
 2018-12-09 21:21:06 2018-12-12 10:40:36 20121
 2018-12-09 21:21:06 2018-12-12 10:41:18 20209
 2018-12-09 21:21:06 2018-12-12 10:41:19 20211
 ...
 2018-12-09 21:21:06 2018-12-12 22:57:15 32691
 2018-12-09 21:21:06 2018-12-12 22:58:04 32761
 2018-12-12 23:52:51 2018-12-12 23:53:32 0
 2018-12-12 23:52:51 2018-12-13 00:25:12 11
 2018-12-12 23:52:51 2018-12-13 00:25:22 23

時間範囲指定した間の、最新の累積値だけ取得できるのかと思ったら、その範囲での累積値の変化が取得できるようでした。
注目すべきポイントが12/12 23:52:51のタイミングで、それまで一定だったstartの値が変わっていて、歩数が0にリセットされているところです。
Android端末では、端末を再起動すると歩数累積がリセットされるので、それによるものだと思います。
つまり、その様子も取得できるということになりますね。

TYPE_STEP_COUNT_DELTA

こちらは、前回計測時との差分を取得できるDataTypeです。
コードとしては、先ほどのコードのDataType.TYPE_STEP_COUNT_CUMULATIVEDataType.TYPE_STEP_COUNT_DELTAに変えるだけでOKです。

そうしたら、以下のような情報を取得できました。

start               end                 value
2018-12-12 10:39:36 2018-12-12 10:40:36 10
2018-12-12 10:40:36 2018-12-12 10:41:19 90
2018-12-12 10:41:19 2018-12-12 10:42:19 129
...
2018-12-12 22:56:15 2018-12-12 22:57:14 106
2018-12-12 22:57:14 2018-12-12 22:57:15 2
2018-12-12 22:57:15 2018-12-12 22:58:04 70

CUMULATIVEでは、端末再起動時以外はstartが固定されてたのに対し、こちらでは毎回startが変わっているのが分かると思います。
このように、DELTAでは、一定時間ごとにその間での歩数を取得することができます。これらを足し合わせていったら、CUMULATIVEで取得した値になるということですね。

AGGREGATE_STEP_COUNT_DELTA

こちらは、指定した間隔ごとに値が集計された結果を、取得することができるDataTypeです。
例えば、日ごとに集計したい場合は以下のようなコードになります。

val start = 1544540400000 // 2018-12-12 00:00:00
val end = Date().time // 現在時刻

val request = DataReadRequest.Builder()
    .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
    .setTimeRange(start, end, TimeUnit.MILLISECONDS)
    .bucketByTime(1, TimeUnit.DAYS) // 集計間隔を1日毎に指定
    .build()

Fitness.getHistoryClient(this, GoogleSignIn.getLastSignedInAccount(this))
    .readData(request)
    .addOnSuccessListener {
        val buckets = it.buckets // 集計データはbucketsというところに入ってくる
        buckets.forEach { bucket ->
            val start = bucket.getStartTime(TimeUnit.MILLISECONDS)
            val end = bucket.getEndTime(TimeUnit.MILLISECONDS)
            val dataSet = bucket.getDataSet(DataType.AGGREGATE_STEP_COUNT_DELTA)
            val value = dataSet.dataPoints.first().getValue(Field.FIELD_STEPS)
            Log.d("Aggregate", "$start $end $value")
        }
    }

そうすると、以下のような情報が取得できました。

start               end                 value
2018-12-12 00:00:00 2018-12-13 00:00:00 12650
2018-12-13 00:00:00 2018-12-13 02:21:34 52

つまりこれは、日毎の歩数ですね。これは大変便利ですね!
歩数計サービスにおいては一番使う機能な気がします。

まとめ

GoogleFitAPIを使えば、スマホで計測した歩数を、色んなパターンで受け取ることができます。
作りたいサービスによって使い分けることが出来ると良い感じですね!

GoogleFitAPIにはまだまだ色んな機能があります。
こちらを活用して、ヘルスケアサービスをどんどん盛り上げていけたらと思います!

46
57
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
46
57