Plan for performance

We recommend adhering to the following best practice guidelines, to make sure your app performs well alongside Health Connect.

Write data

Apps must only write own-sourced data to Health Connect.

If data in your app has been imported from another app, then the responsibility falls onto the other app to write its own data to Health Connect.

It's also a good idea to implement logic that handles write exceptions such as data being outside of bounds, or an internal system error. You can apply your backoff and retry strategies on a job scheduling mechanism. If writing to Health Connect is ultimately unsuccessful, make sure that your app can move past that point of export. Don't forget to log and report errors to aid diagnosis.

When tracking data, there are a couple of suggestions you can follow depending on the way your app writes data.

Passive tracking

This includes apps that perform passive fitness or health tracking, like recording steps or heart rate continuously in the background.

Your app needs to periodically write data into Health Connect in the following ways:

  • On every sync, only write new data and update data that was modified since the last sync.
  • Chunk requests to at most 1000 records per write request.
  • Use WorkManager to schedule periodic background tasks, with a time period of at least 15 minutes.
  • Restrict tasks to run only when the device is idle and is not low on battery.

    val constraints = Constraints.Builder()
        .requiresBatteryNotLow()
        .requiresDeviceIdle(true)
        .build()
    
    val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
            15,
            TimeUnit.MINUTES,
            5,
            TimeUnit.MINUTES
        )
        .setConstraints(constraints)
        .build()
    

Active tracking

This includes apps that perform event-based tracking such as exercise and sleep, or manual user input such as nutrition. These records are created when the app is in the foreground, or in rare events where it is used a few times in a day.

Ensure that your app doesn't keep Health Connect running for the entire duration of the event.

Data must be written into Health Connect in one of two ways:

  • Sync data into Health Connect after the event is complete. For example, sync data when the user ends a tracked exercise session.
  • Schedule a one-off task using WorkManager to sync data later.

Sample rate

When writing data into Health Connect, use appropriate sample rates to help reduce storage load. For example, it's worth thinking about how frequently step count data needs to be recorded, or what kind of sample rate data types linked to an active workout (like speed) it requires.

Not every data type requires the same sample rate. There is little benefit to updating step count data every second, as opposed to a less frequent cadence such as every 60 seconds. However, higher sample rates may give users a more detailed and granular look at their health and fitness data. Sample rate frequencies needs to strike a balance between detail and performance.

Sync data

The following factors affect the syncing process.

Token expiration

Since an unused Changes token expires within 30 days, you must use a sync strategy that avoids losing information in such a case. Your strategy could include the following approaches:

  • Search your app datastore for the most recently consumed record that also has an id from Health Connect.
  • Request records from Health Connect that begin with a specific timestamp, and then insert or update them in your app's datastore.
  • Request a Changes token to reserve it for the next time it's needed.

Recommended Changes management strategies

In case your app is getting invalid or expired Changes tokens, we recommend the following management strategies depending on its application in your logic:

  • Read and dedupe all data. This is the most ideal strategy.
    • Store the timestamp of the last time they read data from Health Connect.
    • On token expiry, re-read all data from the most recent timestamp or for the last 30 days. Then, dedupe it against the previously read data using identifiers.
    • Ideally, implement Client IDs since they are required for data updates.
  • Only read data since the last read timestamp. This results in some data discrepancies around the time of Changes token expiry, but the time period is shorter that could take a few hours to a couple of days.
    • Store the timestamp of the last time they read data from Health Connect.
    • On token expiry, read all data from this timestamp onwards.
  • Delete then read data for the last 30 days. This aligns more closely with what happens on the first integration.
    • Delete all data read by the app from Health Connect for the last 30 days.
    • Once deleted, read all of this data again.
  • Read data for last 30 days without deduping. This is the least ideal strategy, and results in having duplicate data displayed to users.
    • Delete all data read by the app from Health Connect for the last 30 days.
    • Allow duplicate entries.

Data type Changes tokens

If your app consumes more than one data type independently, use separate Changes Tokens for each data type. Only use a list of multiple data types with the Changes Sync API if these data types are either consumed together or not at all.

Foreground reads

Apps can only read data from Health Connect while they are in the foreground. When syncing data from Health Connect, access to Health Connect may be interrupted at any point. For example, your app must handle interruptions midway through a sync when reading a large amount of data from Health Connect, and continue the next time the app is opened.

Import timings

As your app can't get notified of new data, check for new data at two points:

  • Each time your app becomes active in the foreground. In this case, use lifecycle events.
  • Periodically, while your app remains in the foreground. Notify users when new data is available, allowing them to update their screen to reflect the changes.

Rate limits

In rare circumstances, Health Connect places rate limits on requests from your app. This is done to limit battery impact and device performance.

  • We strongly recommended following best practice guidelines to prevent your app's requests from being rejected due to rate limiting.
  • Apps should be resilient to rate limiting. For example, data in the background can be written during the next periodic task, in case of requests failing due to rate limiting.

Onboard your app

Many apps have a custom onboarding flow such as feature education or asking user consent. Developers are strongly recommended to export an onboarding activity that Health Connect launches when the user interacts with the app for the first time. To do so, add the following in your manifest:

<!-- Required to support pre-Android 14 devices with APK Health Connect -->
<activity
  android:name=".OnboardingActivity"
  android:exported="true"
  android:permission="com.google.android.apps.healthdata.permission.START_ONBOARDING"
  <intent-filter>
    <action android:name="androidx.health.ACTION_SHOW_ONBOARDING"/>
  </intent-filter>
</activity>
<!-- Required to support Android 14+ devices with platform Health Connect -->
<activity-alias
  android:name="UAndAboveOnboardingActivity"
  android:exported="true"
  android:targetActivity=".OnboardingActivity"
  android:permission="android.permission.health.START_ONBOARDING">
  <intent-filter>
    <action android:name="android.health.connect.action.ACTION_SHOW_ONBOARDING" />
  </intent-filter>
</activity-alias>

Please note that support for this feature is not yet available for Android 14 but is coming soon.

When a user attempts to connect your app to Health Connect, the exported activity is launched. This activity must do the following:

  • Display any relevant user education such as explaining what data is written or read.
  • Ask the user to grant consent if required.
  • Make a permissions request to Health Connect.
  • Carry out any other application specific logic such as scheduling a periodic worker.
  • Once complete, allow the user to dismiss the activity.

For apps that don't export an onboarding activity, Health Connect instead brings the user to the Manage permissions screen once the user attempts to connect the app. This may be acceptable for apps where permissions being granted is the only prerequisite for the integration to function.

Note that the onboarding activity may be launched more than once, for example if the user later revokes permissions to your app and then reconnects it.