メインコンテンツへスキップ

Capacitor における Google Fit から Health Connect への移行

2026年のFit API終了に備え、Capacitor アプリをGoogle FitからHealth Connectへ移行する方法:データ型のマッピング、権限、クエリ、Playストアの審査について。

Capacitor フィットネスアプリを Google Fit から Health Connect へ移行する

Google Fit から Health Connect への移行とは、Android 上の Capacitor アプリにおけるすべての Fit API 呼び出しを Health Connect に、iOS 版も提供している場合は HealthKit に置き換えることを意味します。Google は 2024 年 5 月 1 日に Google Fit の新規登録を停止しており、Fit API のサポートは 2026 年末までとなっています。本ガイドでは、Fit のデータ型と呼び出しを Health Connect にマッピングし、置き換え用の code を併せて示し、 @capgo/capacitor-health健康関連の権限に伴う Play Console の審査についても解説します。

Google Fit の廃止スケジュール

日付 何が起きたのか
2024年5月1日 Google Fit API の新規開発者登録を停止
2024年から2026年 既存の Fit 連携は引き続き動作し、Google は開発者に Health Connect の利用を案内しています
2026 REST API を含む Fit API が非推奨となります
2026年末 サポート終了。Googleは正確な終了日を公表していません

Googleの移行FAQでは、同じ形のFit REST APIに代わるものはないとされています。オンデバイスアプリはHealth Connectへ、クラウド連携はアカウントベースのGoogle Health APIへ移行します。どこかで具体的な終了日が引用されていても、計画を立てる前にGoogleのFAQと照合してください。

Health Connectに移行すると何が変わるか

Google Fit Health Connect
データの保存先 Googleアカウント(クラウド上) デバイス上
認証 OAuth 2.0(fitnessスコープ)、Google Sign-In データ型ごとのAndroid実行時権限
セットアップ クラウドプロジェクト、OAuthクライアント、SHA-1フィンガープリント Manifest権限、プライバシーポリシー画面
利用可否 Play services 対応の Android デバイス Android 14 以降に標準搭載、それ以前のバージョンでは Google Play からのアプリ
履歴 アカウントの全履歴 デフォルトで直近30日間、それ以前のデータは READ_HEALTH_DATA_HISTORY
Web/サーバーアクセス REST API なし(クラウドには Google Health API を使用)
iOSと 非対応 非対応、HealthKit を使用
ストア審査 機微なスコープの OAuth 検証 Play Console での Health Connect 宣言

最大の製品変更はデバイス中心のモデルです。1台のスマートフォン上の Health Connect データは別のデバイスからは見えません。アプリで複数デバイス間の履歴を表示する場合は、測定値を独自のバックエンドに同期してください。

Fit のデータ型を Health Connect にマッピング

Google Fit データ型 Health Connect レコード @capgo/capacitor-health 型
com.google.step_count.delta StepsRecord steps
com.google.distance.delta DistanceRecord distance
com.google.calories.expended TotalCaloriesBurnedRecord / ActiveCaloriesBurnedRecord totalCalories / calories
com.google.calories.bmr BasalMetabolicRateRecord basalCalories
com.google.heart_rate.bpm HeartRateRecord heartRate
com.google.weight WeightRecord weight
com.google.height HeightRecord height
com.google.body.fat.percentage BodyFatRecord bodyFat
com.google.sleep.segment SleepSessionRecord ステージ付き sleep
com.google.oxygen_saturation OxygenSaturationRecord oxygenSaturation
com.google.blood_pressure BloodPressureRecord bloodPressure
com.google.blood_glucose BloodGlucoseRecord bloodGlucose
com.google.body.temperature BodyTemperatureRecord bodyTemperature
com.google.hydration HydrationRecord dietaryWater
com.google.nutrition NutritionRecord dietaryEnergyConsumed (エネルギーのみ)
com.google.activity.segment および Sessions API ExerciseSessionRecord workouts (経由で読み取り) queryWorkouts)

直接の対応がない Fit 型

  • ハートポイント (com.google.heart_minutes)、離れるときは ムーブ・ミニッツ (com.google.active_minutes) は Google Fit のスコアでした。Health Connect はこれらのスコアではなく、生データを保存します。心拍数とエクササイズセッションから、独自の指標を再計算してください。
  • アクティビティサンプル 秒単位のアクティビティタイプを持つものは、セグメント付きのエクササイズセッションに置き換わります。
  • 位置情報サンプル ワークアウト内のものは、 ExerciseRoute Health Connect のデータになります。これには別途権限が必要で、プラグインからは公開されていません。
  • ケイデンス、速度、パワー は Health Connect に存在しますが(StepsCadenceRecord, SpeedRecord, PowerRecord) プラグインの型ではカバーされていません。これらに依存している場合は、小さなカスタムネイティブメソッドを実装するのが最短ルートです。

code を書く前に監査: すべてをリストアップ DataType および呼び出すすべての API (History, Recording, Sessions, Sensors, Config, REST) を列挙し、それぞれをマッピング済み、再計算、削除のいずれかとしてマークします。

ステップ 1: Google Fit の削除

Android プロジェクトと JavaScript から Fit 統合を削除します:

  • 削除 com.google.android.gms:play-services-fitness また、Fit のみに使用している場合は、 play-services-auth と build.gradle.
  • Google Cloud から Fit OAuth クライアントを削除し、同意画面からフィットネススコープを削除します。
  • 以前使用していたコミュニティ版 Google Fit Capacitor プラグインをアンインストールし、次に実行します bunx cap sync.

Fit code は、新しいバージョンが公開されるまでブランチに保持してください。ユーザーから要求があった場合、過去データをエクスポートできるようにするためです。

ステップ 2: ヘルスプラグインのインストール

bun add @capgo/capacitor-health
bunx cap sync

@capgo/capacitor-health Capacitor 8 をサポートし、Android では Health Connect、iOS では HealthKit を使用します。Android が必要です minSdk 26.

Androidの設定

このプラグインは、サポートされているタイプの Health Connect の読み取りと書き込み権限をマニフェストにマージし、さらに <queries> Health Connect パッケージのエントリと権限理由アクティビティを追加します。以下が必要です:

  1. プライバシーポリシーを提供してください。 Health Connect は権限シートから開きます。または、 android/app/src/main/assets/public/privacypolicy.htmlを追加するか、 android/app/src/main/res/values/strings.xml:
<string name="health_connect_privacy_policy_url">https://example.com/privacy</string>
  1. にURLを設定してください。 権限を整理します。 tools:node="remove":
<uses-permission
    android:name="android.permission.health.WRITE_BLOOD_GLUCOSE"
    tools:node="remove" />
  1. 必要に応じて、履歴へのアクセスを追加します。 で残りを削除してください。 READ_HEALTH_DATA_HISTORY:
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY" />

iOSの設定

必要に応じて履歴アクセスを追加します。 Info.plist:

<key>NSHealthShareUsageDescription</key>
<string>Show your steps and workouts in the app.</string>
<key>NSHealthUpdateUsageDescription</key>
<string>Save the workouts you record in the app.</string>

Health Connect は、ユーザーが

を許可しない限り、読み取りを過去30日程度に制限します。

import { Health } from '@capgo/capacitor-health';

export async function ensureHealthAvailable() {
  const result = await Health.isAvailable();
  if (result.available) return true;

  // On Android, send the user to install or update Health Connect
  if (result.platform === 'android') {
    await Health.openHealthConnectSettings();
  }
  console.warn('Health store unavailable:', result.reason);
  return false;
}

Xcode で HealthKit の機能を有効にし、

に用途文字列を追加してください。

Fit のフローは、Google サインイン、フィットネススコープの要求、API 呼び出しでした。新しいフローは単一の権限シートです:

const status = await Health.requestAuthorization({
  read: ['steps', 'distance', 'calories', 'heartRate', 'sleep', 'workouts'],
  write: ['weight'],
  requestHistoryAccess: true, // Android only
});

if (status.readDenied.length > 0) {
  // explain what will not work and offer openHealthConnectSettings()
}
if (status.historyAccessAvailable === false) {
  // provider too old: only the last 30 days are readable
}

権限はデータタイプごとに設定され、ユーザーは任意の部分集合を許可できます。 checkAuthorization ユーザーは Health Connect の設定でいつでもアクセスを撤回できるため、アプリの起動時に同じオプションを使用してください。iOS では、HealthKit はプライバシー保護のため読み取り拒否を隠すため、空の結果は「データなし」または「アクセスなし」を意味する可能性があります。

ステップ 5: History API の読み取りを置き換える

Fit の readData 生サンプルの呼び出しは readSamples:

const end = new Date();
const start = new Date(end.getTime() - 24 * 60 * 60 * 1000);

const { samples } = await Health.readSamples({
  dataType: 'heartRate',
  startDate: start.toISOString(),
  endDate: end.toISOString(),
  limit: 500,
  ascending: true,
});

for (const s of samples) {
  console.log(s.startDate, s.value, s.unit, s.sourceName, s.deviceType);
}

sourceName になり、Android では deviceType (watch, phone, chestStrapなど) Fit のデータソースオブジェクトを置き換えます。両方が存在する場合、ウォッチのデータを優先するためにこれらを使用します。

ステップ 6: バケット化・集計読み取りを置換

Fit の bucketByTime と aggregate に変わります queryAggregated:

const { samples: daily } = await Health.queryAggregated({
  dataType: 'steps',
  startDate: new Date(Date.now() - 7 * 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
  bucket: 'day',          // 'hour' | 'day' | 'week' | 'month'
  aggregation: 'sum',
});

const { samples: hr } = await Health.queryAggregated({
  dataType: 'heartRate',
  bucket: 'hour',
  aggregation: ['min', 'average', 'max'],
  startDate: new Date(Date.now() - 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
});
// hr[i].values.min, hr[i].values.average, hr[i].values.max

生のサンプルを合計するのではなく、常に歩数を集計してください。Health Connect は集計時に複数アプリの重複データを排除するため、ウォッチとスマートフォンの両方で歩数を記録していると、生の合計では二重計上されることがよくあります。

ステップ 7: セッションの API を置換

Fit のセッションはエクササイズセッションに対応します:

const { workouts, anchor } = await Health.queryWorkouts({
  workoutType: 'running',
  startDate: new Date(Date.now() - 30 * 86_400_000).toISOString(),
  endDate: new Date().toISOString(),
  limit: 50,
});

for (const w of workouts) {
  console.log(w.workoutType, w.duration, w.totalDistance, w.totalEnergyBurned);
}
// pass `anchor` back to fetch the next page

リクエスト workouts における read まず権限を設定してください。このプラグインはワークアウトを読み取りますが、エクササイズセッションの書き込みは行いません。アプリでワークアウトを記録する場合は、元になるサンプル(距離、カロリー、心拍数)を書き込み、セッション自体はバックエンドに保持するか、そのためのネイティブメソッドを追加してください: ExerciseSessionRecord.

ステップ 8: insert を置換

Fit の insertData に変わります saveSample:

await Health.saveSample({
  dataType: 'weight',
  value: 72.4, // kilograms
  startDate: new Date().toISOString(),
});

await Health.saveSample({
  dataType: 'bloodPressure',
  value: 120,
  systolic: 120,
  diastolic: 80,
  startDate: new Date().toISOString(),
});

値は各タイプのデフォルト単位(キログラム、メートル、キロカロリー、bpm)を使用する必要があります。この metadata オプションは Health Connect では無視されます。

ステップ 9: Google Play の審査を通過する

ヘルス権限は追加審査の対象になります:

  1. Play Consoleで、次を開きます: アプリのコンテンツ を完了し、 ヘルスアプリ 申告と Health Connect の権限フォーム。要求するすべての権限について、理由を説明してください。
  2. Play Console にリンクされているプライバシーポリシーと、Health Connect シートに表示されるプライバシーポリシーが、ヘルスデータの利用方法を説明していることを確認してください。
  3. 更新: データ セーフティ フォーム: 健康・フィットネスデータ、収集の有無、共有の有無。
  4. 正当な理由がある権限のみを宣言したビルドを提出してください。余分な権限の宣言は、最もよくあるリジェクト原因です。

通常のアップデートよりも審査に時間がかかることを想定してください。この移行は他の機能と混ぜず、単独のリリースとして配信しましょう。

ステップ 10: ユーザーの期待値を移行する

  • 履歴データは今後 Health Connect から取得されること、また履歴へのアクセスを許可するまで古いデータは30日分に限られる場合があることをユーザーに伝えます。
  • アプリが Google Fit をクラウド同期に使っていた場合は、その役割を今すぐ自社バックエンドへ移してください。
  • 「Google Fit と連携」ボタンを削除し、Android では「Health Connect と連携」、iOS では「Apple Health と連携」に名前を変更します。

トラブルシューティング

isAvailable() Android 13 では false を返します: Health Connect がインストールされていないか、バージョンが古いです。次を呼び出してください openHealthConnectSettings().

権限のシートが表示されない: 権限がマージされたマニフェストに宣言されていないか、次で削除されています tools:node="remove"を確認してください。 android/app/build/intermediates/merged_manifests.

読み取りは30日分のみ返されます: リクエスト requestHistoryAccess: true および宣言する READ_HEALTH_DATA_HISTORY.

歩数合計がGoogle Fitより多い: 生のサンプルを合算しています。次を使用してください: queryAggregated.

iOSで結果が空になる: データがないか、読み取り権限が拒否されているかのどちらかです。HealthKitではどちらかは判別できません。

Play Consoleでアップデートが拒否される: 未宣言または正当性のないHealth Connectの権限を削除し、明確な理由を添えて再提出してください。

移行を段階的にリリースする

The native part (plugin, manifest, HealthKit capability) needs a store release. After that, queries, UI and data mapping are JavaScript, which you can iterate on with Capgo Live Updates ユーザーが新しいフローをテストしている間に。ライブセンサーデータも読み取る場合は、こちらのガイドを参照してください Capacitor で心拍数モニターを構築する、および ヘルスプラグインのドキュメント すべてのデータタイプに対応。

Capacitor アプリ向けの Live Updates

Web レイヤーのバグが本番で発生したら、App Store の審査を何日も待たずに Capgo で修正を配信しましょう。ネイティブの変更は通常の審査フローに残したまま、ユーザーはバックグラウンドでアップデートを受け取れます。

最新のブログ記事

Capgoは、真にプロフェッショナルなモバイルアプリを作るために必要な最高のインサイトを提供します。