はじめに
私は、ヘルスケア事業部で、スマホの歩数計を活用したサービスの開発に携わっており、主に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
を作成し、HistoryClient
のreadData
を呼び出してあげます。
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_CUMULATIVE
をDataType.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にはまだまだ色んな機能があります。
こちらを活用して、ヘルスケアサービスをどんどん盛り上げていけたらと思います!