Eyes, JAPAN Blog > “Introducing Google Health Connect: The Unified Health and Fitness Data Management Platform for Android”

“Introducing Google Health Connect: The Unified Health and Fitness Data Management Platform for Android”

Tang

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

What is Health Connect (Google)?

Health Connect is a health data management platform on Android. Google launched Health Connect to integrate health data and provide a unified platform for developers to read and write health data using a single API. For users, Health Connect provides a unified management platform for health data, allowing them to view and manage their health data in one place.
Google Health Connect: Google launches Health Connect in beta version to securely share fitness data across Android devices - The Economic Times

Why is health data integration necessary?

Android’s ecosystem includes a variety of devices and platforms, each with its own health data management platform. These platforms are independent, and users need to manage health data on different platforms. This makes health data management inconvenient for users and difficult to integrate. To solve this problem, Google launched Health Connect.

Other APIs

Formerly known as the Fit Android API
Google has decided to discontinue the Fit Android API by the end of 2024. Therefore, developers should migrate to Health Connect as soon as possible. Health Connect is the successor to the Google Fit Android API and provides a unified management platform for health data. Developers can read and write health data on this platform.
Fitbit Web API
The Fitbit Web API is an API for reading and writing health data from Fitbit devices. It provides a unified management platform for health data, allowing developers to read and write health data on this platform. If developers are focused on developing using Fitbit, they can use the Fitbit Web API.
Google Fit REST API
The Google Fit REST API can aggregate and integrate data from multiple sources, including Google Fit. Users can store, share, and manage data in the cloud. Therefore, non-Android platform developers are advised to use the Google Fit REST API.

How to use Health Connect?

Usage Requirements
Android API version 28 or higher (Android 9.0 or higher) and installed Google Play Services
Kotlin version 1.3.50 or higher (currently does not support Java)

Step 1: Install Health Connect

Search for Health Connect in the Google Play Store and install it. (Health Connect is pre-installed on Android 14 and above)

Step 2: Add Health Connect SDK

Add the Health Connect SDK to the build.gradle file. We recommend using alpha09 because alpha10 has a bug that can cause the program to crash.
dependencies {
    …
    implementation “androidx.health.connect:connect-client:1.0.0-alpha11”
    …
}

Step 3: Obtain the Health Connect client

1. Declare the Health Connect package name in the AndroidManifest.xml file.

<queries>
   <packageandroid:name=”com.google.android.apps.healthdata”/>
</queries>

2. Obtain the Health Connect client in the Fragment.

// Check if available and installed

if (HealthConnectClient.isProviderAvailable(requireContext())) {

    // Health Connect is available and installed.

    val healthConnectClient = HealthConnectClient.getOrCreate(requireContext())

    // Use the healthConnectClient object to perform health data queries or other operations

    Log.d(ContentValues.TAG, "Health Connect is available")

} else {

    // Health Connect is not available

    Toast.makeText(requireContext(), "Health Connect is not installed", Toast.LENGTH_SHORT).show()

    Log.d(ContentValues.TAG, "Health Connect is not installed")

    // Open the Google Play Store page for Health Connect

    val dialog = HealthConnectInstallDialogFragment()

    dialog.show(parentFragmentManager, "HealthConnectInstallDialog")

}

Step 4: Declare permissions

Because we are using version alpha09 of the SDK, the method for declaring permissions is slightly different. Create an array resource in res/values. (Here, since we only need to read data, there is only a permission for reading data.)
<?xml version="1.0" encoding="utf-8"?>

   <resources>

  <arrayname="health_permissions">

    <item>androidx.health.permission.HeartRate.READ</item>

    <item>androidx.health.permission.Steps.READ</item>

    <item>androidx.health.permission.Distance.READ</item>

    <item>androidx.health.permission.ExerciseSession.READ</item>

  </array>

</resources>
Also, declare permissions in the AndroidManifest.xml file.
<activity
        android:name=".MainActivity"
        android:exported="true"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <!-- For the Health Connect -->
        <!-- (a) For alpha09 and below, reference permissions resource -->
        <meta-data
            android:name="health_permissions"
            android:resource="@array/health_permissions" />
        <!-- (b) handle intent -->
        <intent-filter>
            <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
        </intent-filter>

        <!-- For the email the feedback/error-->
        <intent-filter>
            <action android:name="android.intent.action.SENDTO" />
            <data android:scheme="mailto" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
</application>

Step 5: Request permissions

private lateinit var healthConnectClient: HealthConnectClient

val PERMISSIONS =
    setOf(
        HealthPermission.createReadPermission(HeartRateRecord::class),
        HealthPermission.createReadPermission(StepsRecord::class),
        HealthPermission.createReadPermission(DistanceRecord::class),
        HealthPermission.createReadPermission(ExerciseSessionRecord::class)
    )
// Create the permissions launcher.
private val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
private val requestPermissions =
    registerForActivityResult(requestPermissionActivityContract) { granted ->
        if (granted.containsAll(PERMISSIONS)) {
            // Permissions successfully granted
            Log.d(ContentValues.TAG, "Permissions successfully granted")
            // Now you can read the steps data
            val job = CoroutineScope(Dispatchers.Main).launch {
                val healthConnectClient = HealthConnectClient.getOrCreate(requireContext())
                checkPermissionsAndRun(healthConnectClient)
            }
        } else {
            // Lack of required permissions
            // Show an error message or request permissions again
            Log.d(ContentValues.TAG, "Permissions required failed")
        }
    }
Example, read the last exercise data.
    suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
        val granted = healthConnectClient.permissionController.getGrantedPermissions(PERMISSIONS)
        if (granted.containsAll(PERMISSIONS)) {
            Log.d(ContentValues.TAG,"Permission Granted")
            // Get last exercise
            var lastExerciseMap: Map<String, String> = getLastExercise(healthConnectClient)
            if (lastExerciseMap["Key"] == "Value"){
                Log.d(TAG, "No Data")
            } else {
                Log.d(TAG, "Last Exercise: ${lastExerciseMap["Key"]}")
            }
        } else {
            Log.d(ContentValues.TAG,"Asking for Permission")
            requestPermissions.launch(PERMISSIONS)
        }
    }

    suspend fun getLastExercise(healthConnectClient: HealthConnectClient): Map<String, String> {
        val lastExercise = mutableMapOf<String, String>()
        val currentDate = LocalDate.now(zoneId)
        val currentDateTime = ZonedDateTime.now(zoneId)
        val sevenDaysAgoDateTime = currentDateTime.minusDays(7) // subtract 7 days from the current date time to get 7 days ago
        val startTime = getStartTime(sevenDaysAgoDateTime.toLocalDate())
        val endTime = ZonedDateTime.of(currentDate, currentDateTime.toLocalTime(), zoneId).toInstant() // combine the end time with the current date in Tokyo time
        val response =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    ExerciseSessionRecord::class,
                    timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
                )
            )
        if (response.records.isEmpty()) {
            // No records found, output step count as 0
            Log.d(ContentValues.TAG, "Exercise None Between ${startTime} ~ ${endTime}")
            lastExercise["Key"] = "Value"
        } else {

            val mostRecentRecord = response.records[response.records.size - 1]
            val durationStart = mostRecentRecord.startTime
            val formatter = DateTimeFormatter.ofPattern("MM月dd日 HH:mm").withZone(zoneId)
            val formattedDurationStart = formatter.format(durationStart)

            val durationEnd = mostRecentRecord.endTime
            lastExercise["Type"] = getExerciseType(mostRecentRecord.exerciseType)
//            lastExercise["Start"] = durationStart.toString()
            lastExercise["Start"] = formattedDurationStart
            lastExercise["End"] = durationEnd.toString()
            lastExercise["Duration"] = getActivityDuration(healthConnectClient, durationStart, durationEnd)
            lastExercise["HeartRate"] = getActivityHeartRate(healthConnectClient, durationStart, durationEnd).first
            lastExercise["StepsCount"] = getActivityStepsCount(healthConnectClient, durationStart, durationEnd).toString()
        }
        return lastExercise
    }

Special note

If the user refuses permission requests twice, your application will be permanently locked and unable to request permissions again. If your application encounters this situation during development and testing, you can reset the permission request count by following these steps:
1. Open the Health Connect app.
2. Go to app permissions.
3. Select your app.
4. Toggle the “All allowed” switch.
5. Toggle the “All allowed” switch again to remove all permissions.
6. When prompted, select “Delete all.”
7. Alternatively, use adb to clear the cache for the Health Connect package.
More info [Health Connect](https://developer.android.com/guide/health-and-fitness/health-connect

Comments are closed.