【Flutter/Health】
端末から歩数情報を取得
前提知識と実装手順・つまずきポイントを紹介

記事イメージ


(最終更新日:

当社で「チーム・ウォーク」という歩数共有アプリ(iOS/Android対応)をFlutterベースで開発して今も公開中です。

このプロダクトではスマホ端末内で歩数の情報を取得する必要がありましたので、Flutterでヘルスケア情報が取得可能なパッケージ"Health"を利用しています。

このパッケージ、取得されるデータ構造や取得方法に要注意ポイントが多数あると感じますので、本記事で共有したいと思います。

これを知らないとハマる可能性大。Healthパッケージの歩数データへのアクセス許諾

Healthパッケージのデータ取得許諾プロセスは、iOSの時とAndroidの場合で違っています。(尚、前提として歩数情報はプライバシーデータに該当するため、いずれのプラットフォームも一定の慎重さで取り扱っています。)

iOSの場合は端末内でユーザーに許諾を取りヘルスケアアプリからデータ取得するので単純ですが、Androidの場合はGoogleアカウントに紐づけて許諾を行うため、サーバーへのアクセスが必須です。

Android端末でもGoogle Fitという、iOSでいうヘルスケアアプリに近しいものが存在しているので、何となく同じ感じで端末内にデータがあるのだろうと思ってかかると、理解しがたい事象にぶちあたると思います。

図解:iOSとAndroidの許諾機構の違い
(Healthパッケージがプラットフォーム毎に自動で切り替えしています)
図解:iOSとAndroidの許諾機構の違い<br>(Healthパッケージがプラットフォーム毎に自動で切り替えしています)
AndroidにおけるOAuth同意画面
AndroidにおけるOAuth同意画面

尚、プロダクトリリースにおける要注意ポイントが、Androidの場合はアプリとは別途にGoogleによるGoogle Fit APIの公開審査が必要という点。

Youtubeでのデータ使途の説明動画等が必要の上、細かい指摘でリジェクトが返ってくるので、感触的にはアプリ公開審査より数段高い難易度です。

Googleによる審査が通ってなくても一応100人まで使用可能ですが、以下のような警告画面が表示されます。(赤点線で示したフローで操作すれば使用可能です)
Googleによる審査が通ってなくても一応100人まで使用可能ですが、以下のような警告画面が表示されます

API認証には、GCPコンソールでOAuth同意画面を作成し、審査に提出する必要があります。

図:GCPから審査依頼を出す画面
図:GCPから審査依頼を出す画面

歩数情報を含むアクティビティは気密性の高い個人情報にあたるので厳正に取り扱うべき、という基本的な考え方はいずれのプラットフォームも共通しています。ただその厳正さのアプローチが異なっています。

iOS(Apple)側は「なぜアクセス権が必要なのか」の説明もAppレビューに含まれている一方、Android(Google)は別途審査を行う形式としています。

このGoogleのAPI審査について取組中の状況を以下の関連記事に公開しています。まだ完了はしていませんが、参考にはなると思います。

関連記事:【OAuth申請実録】Google Fit歩数データアクセスのための前提と実務

Healthパッケージでデータを取得する準備

1. iOSのみ:info.plistに

 - NSHealthShareUsageDescription

 - NSHealthUpdateUsageDescription

の2つを追加。Updateしない場合でも、両方加えなければクラッシュします。

2. Androidのみ:GCPコンソールでのAPI認証情報とOath同意画面を作成。GCPコンソールの左側のメニューの「APIとサービス」の中にあります。

途中、SHA-1証明書のフィンガープリントを要求されるので、以下のMacマシンの以下コマンドで証明書を生成します。

ターミナル
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

公開済みのアプリであれば、Play App Signingのキーが使用できます。

Google Play Console内の「設定」→「アプリの完全性」のページにフィンガープリントが記載されています。(2つありますが、アプリ証明鍵の方です)

この部分、詳しくは、Healthの公式ページをご確認ください。上述のHealthパッケージのデータソースの話が分かっていれば、何が書いてあるのかわかると思います。

データ取得の実装コード

ようやくデータを取得する準備ができたので、コードを書いていきます。

以下のコードでは、本日一杯の歩数データを取得しています。

期間と種類を指定して、HealthFactoryクラスのgetHealthDataFromTypesをコールします。HealthDataType.STEPSを変えれば、色々な種類のヘルスデータを取得できます。

Dart
import 'package:health/health.dart';
HealthFactory health = HealthFactory();
final now = DateTime.now();
final List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(
    DateTime(now.year, now.month, now.day, 0, 0, 0),
    DateTime(now.year, now.month, now.day, 23, 59, 59),
    [HealthDataType.STEPS]
);

初回アクセス時に、アクセス許可のユーザー認証画面が起動します。

ユーザーが拒否した場合、空の配列が返ってきます。忘れずに拾って処理しましょう。

iOS側でのデータ取得実装時における要注意ポイント

データ構造をよく見ていれば分かるんですが、デバッグでは気づきにくい点を紹介します。

きちんと意識して実装しないと、正確でない歩数を抽出してしまう可能性があります。

下記の画像内にあるデータ構造からわかる通り、基本的にはsourceIdプロパティで判断すればOKです。

複数のiPhone端末からデータが取得される

getHealthDataFromTypesメソッド(上記コード)のデータ取得ですが、同一AppleIDで複数端末を持っている人がいると、それぞれの端末が混ざった配列が返ってきます。

下の図でsourceNameを見ればわかる通り、2種類の端末のデータを拾っています。何も考えずに全部足すと約2倍になってしまいます。

下の図でsourceNameを見ればわかる通り、2つの端末のデータを拾っています。何も考えずに全部足すと約2倍になってしまいますね。
下の図でsourceNameを見ればわかる通り、2つの端末のデータを拾っています

その他のフィットネス端末からもデータが取得される

ヘルスケアアプリに連携しているフィットネス端末があると、そちらからもデータが取得されデータに入ってきます。下図の通りsourceIdで判断可能です。目的により集計処理を実装しましょう。

尚、ヘルスケアアプリでユーザーに表示される歩数は、他のデバイスも含んだ集計結果が表示される場合があります。したがって、com.apple.healthのみを集計すると、集計結果とヘルスケアアプリの表示内容に差異が生じます。

HealthライブラリのデータをCSVに抽出した図。Apple製品以外からもデータが取得されています。
HealthライブラリのデータをCSVに抽出した図

また、Apple Watchを併用していると、厄介なことにApple Watch分のデータもsourceIdがcom.apple.health.~で取得されます。

こうなるとsourceNameでしか判定不能ですが、このカラムはユーザー側で変更可能なので実装上の判定には使用しにくいのが難点です。

幸いにしてdateToが同一で入ってくる性質があるように見えますので、同一のdateToは弾く等で重複カウントを避けられる可能性があります。(鋭意調査中です)

どうも、上記のように考えていましたがdateToが数秒ずれることも多いようです。なので妥協案としては、FromとToの期間重複を避ける形で積算して集計するのが現実的な手法だと考えられます。(引き続き鋭意調査中です)

Apple Watchを併用している場合の取得データ一覧。赤枠内は同一時間終了のデータで、iPhoneとApple Watchで2重でデータが存在しています。
Apple Watchを併用している場合の取得データ一覧

ヘルスケアにはユーザーが歩数を直接入力でき、Healthライブラリはそのデータも抽出する

ヘルスケアアプリには、歩数を手動で入力して追加する機能があります。

現行バージョンではsourceIdがcom.app.Health(Healthの先頭が大文字)、sourceNameが「ヘルスケア」(言語設定により変わります。ちなみに英語の場合は「Health」。)となりますので注意しましょう。

ヘルスケアには歩数を直接入力できる機能があります。
ヘルスケアには歩数を直接入力できる機能があります
直接入力分も通常の歩数データに含まれて配列として抽出されます。
直接入力分も通常の歩数データに含まれて配列として抽出されます

記事筆者へのお問い合わせ、仕事のご依頼

当社では、IT活用をはじめ、業務効率化やM&A、管理会計など幅広い分野でコンサルティング事業・IT開発事業を行っております。

この記事をご覧になり、もし相談してみたい点などがあれば、ぜひ問い合わせフォームまでご連絡ください。

皆様のご投稿をお待ちしております。

記事筆者へ問い合わせする

※ご相談は無料でお受けいたします。
IT活用経営を実現する - 堺財経電算合同会社