将健康连接从 Android 13(APK)迁移到 Android 14(框架)

健康连接将与 Android 14 一起打包,作为消费者健康数据的通用数据存储层,受细粒度权限保护,并可作为 Android 系统应用访问(本文档中称为“框架”模块)。

开发者应将健康连接 APK(Android 13)视为框架模型的向后兼容层。框架模型将保持与其 APK 前身 100% 的功能一致性。

在从 Android 13 迁移到 14 的过程中,至关重要的是用户体验要尽可能保持流畅和直观。

本文档概述了迁移计划,提供了一些示例迁移场景,并列出了 Jetpack SDK 的更改,这些更改有助于访问健康连接 API。

迁移计划

  1. Android 14 发布后,Google 将切换到提供健康连接作为 Android 系统应用。
  2. 然后,在功能一致性实现后,将从 APK 中回填数据。
  3. 所有入口点都将针对系统应用 UI。
  4. 数据迁移将开始。在迁移进行期间,模块 API 将被暂停,并显示“迁移进行中”状态。这在健康连接 UI 中也将可见。
  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,并在迁移过程中阻止它们。
  3. 当模块版本与 APK 功能兼容时,迁移过程开始 - 即模块版本包含相同或更多功能集。迁移过程开始后,APK 会迁移权限和数据。
    1. 如果两个版本的功能不兼容,则需要升级模块版本。升级完成后,迁移过程将开始。
  4. 迁移完成后,状态更改为“迁移完成”,并解除对模块 API 的阻止。
  5. 现在可以卸载 APK 了。

迁移 UI 元素

以下屏幕由框架模块显示,用于用户教育目的,包括迁移前和迁移期间

图 1. 如果 Health Connect APK 未“感知迁移”,则会显示一个提示,指示用户更新 APK。如果用户拒绝更新,则模块继续运行并开始累积权限和数据

Phone update required


图 2. 如果框架模块需要更新才能使其与功能兼容,则会显示一个提示,要求用户执行更新并重新启动设备。如果用户拒绝更新,则模块继续运行并开始累积权限和数据

APK update needed


图 3. 在迁移过程中会显示一个加载动画,并显示正在同步数据的文本

Data Syncing

数据去重

如果框架模块在任何迁移或基于云的恢复发生之前就开始获取数据和权限,则适用以下规则。

权限

如果框架模块中存在权限,则在迁移过程中会忽略从 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 中指定的意图操作,其值根据其正在作用的 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 开发者预览版本测试您的解决方案,请联系您的 Google POC 获取帮助。

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

  1. 设置compileSDKPreview = UpsideDownCake
  2. 更新清单以包含 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>

<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 移动服务文档