将 Health Connect 从 Android 13 (APK) 迁移到 Android 14(框架)

Health Connect 将与 Android 14 打包在一起,作为消费者健康数据的通用数据存储层,受精细权限保护并可以作为 Android 系统应用(在本文档中统称为框架模块)进行访问。

开发者应将 Health Connect APK (Android 13) 视为框架模型的向后兼容层。框架模型将保留与其 APK 前身完全兼容的功能。

在从 Android 13 转换到 Android 14 期间,尽可能保持流畅直观的用户体验至关重要。

本文档简要介绍了迁移计划,提供了一些迁移场景示例,并列出了 Jetpack SDK(有助于访问 Health Connect API)的相关变更。

迁移计划

  1. Android 14 发布后,Google 将开始以 Android 系统应用的形式提供 Health Connect。
  2. 实现功能对等后,将从 APK 中回填数据。
  3. 所有入口点都将以系统应用界面为目标。
  4. 开始数据迁移。在迁移过程中,模块 API 会被暂停,并显示为“迁移中”状态。该状态也会显示在 Health Connect 界面中。
  5. 迁移完成后,即可卸载 APK。

迁移场景示例

以下是一些场景示例,说明了 intervalseries 数据类型的迁移过程:

示例 1 - 跑步(区间数据)

用户收集了 10 年的跑步纪录,每天跑步 1 小时。这相当于:

  • 锻炼活动记录:365 * 10 * 1
  • 步数:365 * 10 * 1
  • 卡路里:365 * 10 * 1
  • 总计 = 365 * 10 * 3 (365 * 30) = 10,150

鉴于 1 个分块相当于 3,000 条记录,那么上述数据总计约为 4 个分块。

我们的内部测试已确认,典型分块会在大约 1 秒内完成插入,因此上述数据会在大约 4 秒内完成迁移。

示例 2 - 心率(系列数据)

用户收集了 5 年的心率数据(每分钟创建一条记录),总计 2,628,000 条记录。

每个分块包含 3,000 条记录,数据分布在 876 个分块中。由于 1 个分块需要大约 1 秒钟的时间才能完成插入,那么系统将在 15 分钟内完成数据迁移。

建议迁移流程

我们决定选择即时迁移。实际上,这意味着一旦设备升级到 Android 14,APK 将立即变为非活跃状态,可以最大限度地减少用户干预。

我们先来了解下总体迁移过程:

  1. 用户将设备升级到 Android 14。
  2. Jetpack 14 将用户路由到模块 API,并在迁移过程中屏蔽这些模块 API。
  3. 当模块版本与 APK 的功能兼容(即模块版本中包含相同或更多的功能集)时,开始迁移过程。迁移过程开始后,APK 会迁移权限和数据。
    1. 如果这两个版本的功能不兼容,则需要升级模块版本。升级完成后,迁移过程随即开始。
  4. 迁移完成后,状态将更改为“迁移完成”,并且取消屏蔽模块 API。
  5. 现在可以卸载 APK 了。

迁移界面元素

在迁移之前和迁移过程中,框架模块会显示以下屏幕,用于指导用户。

图 1. 如果 Health Connect APK 不具备“迁移感知”能力,则系统会显示一条提示,以指示用户更新 APK。如果用户拒绝更新,该模块将继续运行并开始累积权限和数据:

需要更新手机


图 2. 如果框架模块需要更新才能具有功能兼容性,则系统会显示一条提示,要求用户执行更新并重启设备。如果用户拒绝更新,该模块将继续运行并开始累积权限和数据:

需要更新 APK


图 3. 迁移过程中会显示一个旋转图标,并附有文字,说明正在同步数据。

同步数据

数据去重

如果框架模块在发生任何迁移或云端恢复之前已经开始获取数据和权限,则需遵守以下规则。

权限

如果框架模块中存在权限,则在迁移过程中,系统会忽略从 APK 获取的任何重复权限。

数据

在迁移过程中,系统会忽略源自 APK 的重复数据,优先考虑来自模块的最新数据。

如果客户端提供了记录 ID,则将在 clientRecordId 进行数据去重操作。否则,会将时间间隔(startTimeendTime 用于内部记录,time 用于即时记录)以及数据类型和应用软件包名称视为键。

Jetpack SDK 中的变更

Jetpack SDK 充当 Health Connect APK 和 Health Connect 框架 API 的共用集成点。

OEM 可以开始与 Jetpack 13 集成,这样当 Jetpack 14 推出后,您就可以使用新库并在 Android 14 中对其进行编译。

我们将发布支持向 Android 14 过渡的新版 SDK。您将需要对现有集成进行一些更改,以确保顺利完成过渡。

权限声明

在 Android 13 中,您可以使用自定义权限格式在与清单关联的资源文件中声明权限:

#AndroidManifest.xml

<activity>
    android:name=".RationaleActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
    </intent-filter>
    <meta-data
        android:name="health_permissions"
        android:resource="@array/health_permissions"/>
</activity>

<queries>
    <package android:name="com.google.android.apps.healthdata" />
</queries>

#health_permissions.xml

<resources>
  <array name="health_permissions">
    <item>androidx.health.permission.SleepSession.READ</item>
    <item>androidx.health.permission.SleepStage.READ</item>
    <item>androidx.health.permission.Weight.READ</item>
    <item>androidx.health.permission.Weight.WRITE</item>
  </array>
</resources>

为了支持 Android 14,开发者需要改用标准权限格式:

#AndroidManifest.xml

<uses-permission android:name=”android.permission.health.READ_SLEEP” />
<uses-permission android:name=”android.permission.health.READ_WEIGHT” />
<uses-permission android:name=”android.permission.health.WRITE_WEIGHT” />

<activity>
    android:name=".RationaleActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
    </intent-filter>
</activity>

<queries>
    <package android:name="com.google.android.apps.healthdata"/>
</queries>

打开 Health Connect

大多数第三方应用具有用于打开 Health Connect 应用的按钮,例如 Fitbit 中的“管理访问权限”按钮。

在 Android 13 中,您可以使用软件包名称或通过 androidx.health.ACTION_HEALTH_CONNECT_SETTINGS 操作打开 Health Connect 应用。

在 Android 14 中,您需要使用 Jetpack SDK 中指定的 intent 操作;该操作的取值会根据其正在操作的 Android 版本而有所不同。

@get:JvmName("getHealthConnectSettingsAction") @JvmStatic val ACTION_HEALTH_CONNECT_SETTINGS

获取 Health Connect 客户端

我们创建了一个名为 sdkStatus单一 API(可在 Jetpack 11 中使用),以替换另外两个已废弃的 API(IsSdkSupported()isProviderAvailable())。

活动记录 API 变更

在 alpha10 版中,删除了四个 ExerciseSession 子类型:

  • ExerciseEvent
  • ExerciseLaps
  • ExerciseRepetitions
  • SwimmingStrokes

ExerciseSessionRecord 一样,SleepStage 将成为 SleepSession 的子类型。

ExerciseSessionRecord 子类型和 SleepSession 更改都将在 4 月份的 SDK 更新中发布。

锻炼活动类型更新

以下锻炼活动类型将不再受支持,而是以后作为细分类型进行添加。

  • EXERCISE_TYPE_BACK_EXTENSION
  • EXERCISE_TYPE_BARBELL_SHOULDER_PRESS
  • EXERCISE_TYPE_BENCH_PRESS
  • EXERCISE_TYPE_BENCH_SIT_UP
  • EXERCISE_TYPE_BURPEE
  • EXERCISE_TYPE_CRUNCH
  • EXERCISE_TYPE_DEADLIFT
  • EXERCISE_TYPE_DUMBBELL_CURL_LEFT_ARM
  • EXERCISE_TYPE_DUMBBELL_CURL_RIGHT_ARM
  • EXERCISE_TYPE_DUMBBELL_FRONT_RAISE
  • EXERCISE_TYPE_DUMBBELL_LATERAL_RAISE
  • EXERCISE_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM
  • EXERCISE_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM
  • EXERCISE_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM
  • EXERCISE_TYPE_FORWARD_TWIST
  • EXERCISE_TYPE_JUMPING_JACK
  • EXERCISE_TYPE_JUMP_ROPE
  • EXERCISE_TYPE_LAT_PULL_DOWN
  • EXERCISE_TYPE_LUNGE
  • EXERCISE_TYPE_PLANK
  • EXERCISE_TYPE_SQUAT
  • EXERCISE_TYPE_UPPER_TWIST

替换类型:

  • EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
  • EXERCISE_TYPE_STRENGTH_TRAINING
  • EXERCISE_TYPE_CALISTHENICS

更新日志处理

从 APK 改为 Android 14 时,更新日志不会随之迁移。

迁移完成后,您将开始收到 TOKEN_EXPIREDTOKEN_INVALID 异常通知。应按照以下方式处理这些异常(按照优先顺序):

1. 读取自“上次读取”时间戳之后或过去 30 天内的所有数据,并对数据进行去重处理

存储应用上次从 Health Connect 读取数据的时间戳。令牌过期时,应重新读取该过期时间内或过去 30 天内(以最短者为准)的数据,并使用 UUID 对之前读取的数据进行去重处理。

2. 从“上次读取”时间戳开始读取数据

建立一个时间戳,用于指示上次从 Health Connect 读取数据的时间,并在令牌过期时读取该过期时间之后的所有数据。

3. 删除和重新读取过去 30 天内的数据

删除过去 30 天内从 Health Connect 读取的所有数据,然后重新读取所有这些数据(例如,在应用首次与 Health Connect 集成时执行此操作)。

4. 不进行任何操作(即重新读取过去 30 天内的数据,但不进行去重处理)

只应在万不得已时才这样做,因为存在显示重复数据的相关风险。鉴于 UUID 应已准备就绪,开发者应改为探索选项 1-3。

使用 Jetpack SDK 测试 Android 14 API

Android 14 Jetpack SDK 计划于 2023 年 6 月 7 日与 Android 14 的 Beta 版 3 一起发布。届时,您将需要基于 Android 14 对应用进行编译,这样才能使用 Android 14 Jetpack SDK。

如果您想在 6 月 7 日之前针对 Android 开发者预览版 build 测试解决方案,请与您的 Google 联系人联系以获取帮助。

如果您想基于 Beta 3 版本测试解决方案,则应在 APK 中进行以下更改:

  1. 设置 compileSDKPreview = UpsideDownCake
  2. 更新清单,以包含 Android 14 的 intent:
# AndroidManifest.xml

<uses-permission android:name=”android.permission.health.READ_SLEEP”/>
<uses-permission android:name=”android.permission.health.READ_WEIGHT”/>
<uses-permission android:name=”android.permission.health.WRITE_WEIGHT”/>

<activity>
    android:name=".RationaleActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
    </intent-filter>
</activity>

<activity-alias>
      android:name="AndroidURationaleActivity"
      android:exported="true"
      android:targetActivity=".RationaleActivity"
      android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
      <intent-filter>
        <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
        <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
      </intent-filter>
</activity-alias>

<queries>
    <package android:name="com.google.android.apps.healthdata" />
</queries>

OEM 自定义

在 Android 14 中,Health Connect 的隐私和数据管理控制位于“系统设置”中。

为使数据管理和权限屏幕看起来和感觉像是设备的一部分,Health Connect 提供了使用自定义叠加层的 OEM 主题设置。

如需查看 OEM 样式设置文档,请参阅 Health Connect Google 移动服务文档