Migrar a Conexão Saúde do Android 13 (APK) para o Android 14 (framework)

A Conexão Saúde vai ser empacotada com o Android 14 como uma camada de armazenamento de dados comum para dados de saúde do consumidor, protegida por permissões granulares e acessível como um app do sistema Android (chamado neste documento de "framework").

Os desenvolvedores precisam considerar o APK da Conexão Saúde (Android 13) como uma camada de compatibilidade com versões anteriores para o modelo do framework. O modelo de framework vai manter uma paridade de recursos de 100% com o antecessor do APK.

Durante a transição do Android 13 para o 14, é de vital importância que a experiência do usuário permaneça a mais tranquila e intuitiva possível.

Este documento descreve o plano de migração, fornece alguns exemplos de cenários de migração e lista mudanças no SDK do Jetpack, que facilitam o acesso à API Health Connect.

Plano de migração

  1. Depois que o Android 14 for lançado, o Google vai passar a oferecer a Conexão Saúde como um app do sistema Android.
  2. Os dados serão preenchidos no APK assim que a paridade de recursos for alcançada.
  3. Todos os pontos de entrada serão destinados à interface de apps do sistema.
  4. A migração de dados será iniciada. Enquanto a migração estiver acontecendo, as APIs do módulo serão suspensas com o status "Migração em andamento". Isso também vai ficar visível na interface da Conexão Saúde.
  5. Depois que a migração for concluída, o APK poderá ser desinstalado.

Exemplo de cenários de migração

Confira alguns exemplos de cenários que explicam o processo de migração para os tipos de dados interval e series:

Exemplo 1: corrida (dados de intervalo)

Um usuário coletou registros de corrida por 1 hora todos os dias por 10 anos. Isso equivale a:

  • Registros da sessão de exercícios: 365 * 10 * 1
  • Passos: 365 * 10 * 1
  • Calorias: 365 * 10 * 1
  • Total = 365 * 10 * 3 (365 * 30) = 10.150

Considerando que 1 bloco equivale a 3.000 registros, os dados acima totalizam cerca de 4 blocos.

Nosso teste interno confirmou que um bloco típico leva aproximadamente um segundo para ser inserido, portanto, os dados acima seriam migrados em aproximadamente 4 segundos.

Exemplo 2: frequência cardíaca (dados de série)

Um usuário coletou dados de frequência cardíaca (com um registro criado a cada minuto) por cinco anos, totalizando 2.628.000 registros.

Com 3.000 registros por bloco, os dados são distribuídos em 876 blocos. Considerando que 1 bloco leva aproximadamente um segundo para ser inserido, os dados acima seriam migrados em menos de 15 minutos.

Fluxo de migração proposto

Decidimos optar por uma migração instantânea. Em termos práticos, isso significa que o APK vai ficar inativo assim que o dispositivo for atualizado para o Android 14, com o mínimo de intervenção do usuário.

Vamos dar uma olhada em um fluxo de migração detalhado:

  1. O usuário faz upgrade do dispositivo para o Android 14.
  2. O Jetpack 14 encaminha o usuário para as APIs do módulo e as bloqueia enquanto a migração está em andamento.
  3. O processo de migração começa quando a versão do módulo é compatível com o APK, ou seja, a versão do módulo contém o mesmo conjunto de recursos ou outros. Depois que o processo de migração é iniciado, o APK migra as permissões e os dados.
    1. Se as duas versões não forem compatíveis com os recursos, será necessário fazer upgrade da versão do módulo. Quando o upgrade for concluído, o processo de migração será iniciado.
  4. Quando a migração for concluída, o estado será alterado para "Migração concluída", e as APIs do módulo serão desbloqueadas.
  5. O APK poderá ser desinstalado.

Elementos da interface de migração

As telas abaixo são mostradas pelo módulo do framework para orientar o usuário, tanto antes quanto durante a migração:

Figura 1. Se o APK da Conexão Saúde não reconhecer a migração, um aviso vai aparecer instruindo o usuário a atualizar o APK. Se o usuário recusar a atualização, o módulo continuará funcionando e começará a acumular permissões e dados:

Atualização do smartphone necessária


Figura 2. Se o módulo do framework exigir uma atualização para se tornar compatível com o recurso, um aviso vai aparecer solicitando que o usuário realize a atualização e reinicie o dispositivo. Se o usuário recusar a atualização, o módulo continuará funcionando e começará a acumular permissões e dados:

Atualização do APK necessária


Figura 3. Um ícone de carregamento vai aparecer durante o processo de migração, com um texto explicando que os dados estão sendo sincronizados:

Sincronização de dados

Dados duplicados

Se o módulo do framework começar a adquirir dados e permissões antes de qualquer migração ou restauração baseada na nuvem, as regras abaixo serão aplicadas.

Permissões

Se houver permissões no módulo do framework, todas as permissões duplicadas adquiridas do APK serão ignoradas durante o processo de migração.

Dados

Durante a migração, dados duplicados originados do APK serão ignorados. Os dados mais recentes do módulo têm preferência.

Os dados serão duplicados no clientRecordId se o ID de registro for fornecido pelo cliente. Se não forem, os intervalos de tempo (startTime e endTime para registros internos e time para registros instantâneos) serão tratados como chaves, junto do tipo de dados e do nome do pacote do app.

Mudanças no SDK do Jetpack

O SDK do Jetpack serve como o ponto de integração comum para o APK da Conexão Saúde e para as APIs do framework da Conexão Saúde.

Os OEMs podem começar a integrar o Jetpack 13 para que, quando o Jetpack 14 estiver disponível, você possa adaptar a nova biblioteca e compilá-la no Android 14.

Lançaremos outra versão do SDK com suporte à transição para o Android 14. Para garantir uma transição tranquila, será necessário fazer algumas mudanças na integração atual.

Declaração de permissões

No Android 13, você declara permissões usando um formato de permissões personalizado em um arquivo de recursos vinculado ao manifesto:

#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>

Para oferecer suporte ao Android 14, os desenvolvedores precisam mudar para o formato de permissões padrão:

#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>

Abrir a Conexão Saúde

A maioria dos apps de terceiros tem um botão que abre o app Conexão Saúde, como o botão "Gerenciar acesso" no Fitbit.

No Android 13, você abre o app Conexão Saúde usando o nome do pacote ou com a ação androidx.health.ACTION_HEALTH_CONNECT_SETTINGS.

No Android 14, você precisa usar uma ação da intent especificada no SDK do Jetpack, que tem valores diferentes com base na versão do Android em que está agindo:

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

Como acessar o cliente da Conexão Saúde

Criamos uma única API chamada sdkStatus, disponível no Jetpack 11, para substituir duas outras APIs descontinuadas: IsSdkSupported() e isProviderAvailable().

Mudanças na API de registro da sessão

Quatro subtipos de ExerciseSession foram excluídos como parte da versão alfa10:

  • ExerciseEvent
  • ExerciseLaps
  • ExerciseRepetitions
  • SwimmingStrokes

Assim como acontece com ExerciseSessionRecord, SleepStage se tornará um subtipo de SleepSession.

Os subtipos de ExerciseSessionRecord e as mudanças de SleepSession serão lançados como parte da atualização do SDK de abril.

Atualização do tipo de sessão de exercícios

Os tipos de sessão de exercícios abaixo não terão mais suporte e, em vez disso, serão adicionados como tipos de segmento em uma data posterior:

  • 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

Tipos de substituição:

  • EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
  • EXERCISE_TYPE_STRENGTH_TRAINING
  • EXERCISE_TYPE_CALISTHENICS

Processamento do registro de mudanças

Os registros de mudanças não vão ser migrados como parte da transição do APK para o Android 14.

Após a conclusão da migração, você começará a receber exceções TOKEN_EXPIRED ou TOKEN_INVALID. Elas precisam ser tratadas destas maneiras (em ordem de preferência):

1. Leia e elimine a duplicação de todos os dados desde o carimbo de data/hora "última leitura" ou dos últimos 30 dias

Armazene um carimbo de data/hora de quando um app leu os dados da Conexão Saúde pela última vez. Na expiração do token, os dados precisam ser lidos novamente a partir desse valor ou dos 30 dias anteriores (o que equivale ao mínimo) e a duplicação eliminada em relação aos dados lidos anteriormente usando o UUID.

2. Leia os dados desde o carimbo de data/hora "última leitura"

Estabeleça um carimbo de data/hora que indique quando os dados foram lidos pela última vez na Conexão Saúde e, após a expiração do token, leia todos os dados após esse valor.

3. Exclua e releia os dados dos últimos 30 dias

Exclua todos os dados lidos da Conexão Saúde dos últimos 30 dias e leia todos esses dados de novo (por exemplo, quando os apps são integrados pela primeira vez à Conexão Saúde).

4. Não faça nada (ou seja, leia de novo os dados dos últimos 30 dias e não elimine duplicações)

Isso deve ser usado como último recurso, com um risco associado de mostrar dados duplicados. Em vez disso, os desenvolvedores precisam explorar as opções de 1 a 3, porque os UUIDs já devem estar em vigor.

Como testar APIs do Android 14 com o SDK do Jetpack

O SDK do Jetpack do Android 14 vai ser lançado em 7 de junho de 2023 com a versão Beta 3 do Android 14. É necessário começar a compilar o app no Android 14 para usar o SDK do Jetpack para Android 14.

Se você quiser testar sua solução em relação aos builds da prévia para desenvolvedores do Android até 7 de junho, fale com seu contato de operações de parceiro do Google para receber ajuda.

Se você quiser testar a solução com a versão Beta 3, faça estas mudanças no seu APK:

  1. Defina compileSDKPreview = UpsideDownCake.
  2. Atualize o manifesto para incluir uma intent para o 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>

Personalização de OEM

No Android 14, os controles de privacidade e gerenciamento de dados da Conexão Saúde estão localizados nas configurações do sistema.

Para fazer com que as telas de permissões e gerenciamento de dados pareçam fazer parte do dispositivo, a Conexão Saúde oferece temas de OEM usando sobreposições personalizadas.

Para conferir a documentação sobre o estilo do OEM, consulte a documentação dos Serviços do Google Mobile da Conexão Saúde.