開発部第2グループの天野です。 AndroidアプリにGoogle Fitと連携して歩数取得する方法を調べたので実装方法をご紹介します。
はじめに
基本的に以下の手順で可能です。
Get started on Android | Google Fit | Google Developers
ただ、その中で特に実装前の準備が難しかったため、案件で組み込んだときの手順や注意事項をメモしておきます。何か参考になれば。
調査時に実装したコードも抜粋してサンプルとして載せておきますが、コードは公式やGitHubに転がっているので、そちらを読んでもらっても良いと思います。
前提
- Firebaseでプロジェクトが作成されている
- Googleアカウントの認証はFirebase Authenticationを使用する
- Google FItアプリを端末にインストール済
注意
- OAuth同意画面の審査が4〜6週間かかるので、公開ステータスを
公開
に変更する場合は余裕を持って行う - OAuth ユーザー数の上限(一日に連携を開始できるユーザー数の上限)が設定されているので、既存アプリにGoogle Fit連携を追加する場合は期待できるユーザー数に応じて上限緩和申請が必要
- OAuthのスコープで権限を広くしてしまうと審査が通りづらくなるらしいので、必要な権限を適切に指定する ex)読み込みだけでいいのに、書き込みも要求する。歩数の取得だけでいいのに身体情報の読み込みも要求する
準備
GCP
Fitness APIを有効化する
APIとサービスのダッシュボードにある
APIとサービスの有効化
を押下Fitness API
を検索・選択し、有効化にする
を押下APIとサービスのダッシュボードに
Fitness API
が表示されていれば有効化完了
OAuth同意画面を設定する
APIとサービスのOAuth同意画面で、
外部
を選択して作成
を押下アプリ情報、アプリのドメイン、デベロッパーの連絡先情報の必須情報を入力して
保存して次へ
を押下スコープを追加または削除
を押下し、スコープに.../auth/fitness.activity.read
を追加して更新
を押下テストユーザーを追加し、
保存して次へ
を押下
Firebase
Google Authenticationの設定
Authentication画面でGoogleを選択。有効にし
保存
を押下
フィンガープリントの設定
プロジェクトの設定画面で対象アプリを選択し、
フィンガープリントを追加
を押下google-services.jsonをダウンロードし、Android Studioで組み込み
実装サンプル
Kotlinでの実装サンプルです。
- Gradle(appモジュール)にFitnessとAuthenticationを追加
dependencies { implementation("com.google.android.gms:play-services-fitness:20.0.0") implementation("com.google.android.gms:play-services-auth:19.2.0") }
- Google Fitのインストール確認
fun checkIfFitInstalled(context: Context): Boolean { return try { context.packageManager.getPackageInfo("com.google.android.apps.fitness", PackageManager.GET_ACTIVITIES) true } catch (e: Exception) { false } }
- パーミッション取得
fun checkGoogleSignInFitnessPermission(activity: Activity): Boolean { val fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .build() val account = GoogleSignIn.getAccountForExtension(activity, fitnessOptions) return if (GoogleSignIn.hasPermissions(account, fitnessOptions)) { true } else { GoogleSignIn.requestPermissions(activity, PERMISSION_GOOGLE_ACCOUNT_SIGN_IN, account, fitnessOptions) false } }
- 指定期間の歩数取得
fun getStepCount(activity: Activity, startDate: Date, endDate: Date, listener: OnReadStepCount) { val request = DataReadRequest.Builder() .aggregate(DataType.TYPE_STEP_COUNT_DELTA) .bucketByTime(1, TimeUnit.HOURS) .setTimeRange(startDate.time, endDate.time, TimeUnit.MILLISECONDS) .build() val fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .build() val account = GoogleSignIn.getAccountForExtension(activity, fitnessOptions) if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) { listener.invoke(null) } else { Fitness.getHistoryClient(activity, account) .readData(request) .addOnSuccessListener{ response -> val stepCount = response.buckets .flatMap{it.dataSets} .flatMap{it.dataPoints} .sumBy{it.getValue(Field.FIELD_STEPS).asInt()} listener.invoke(stepCount) } .addOnFailureListener{ Timber.e(it) listener.invoke(null) } } }