Episode 9: Challenges and Solutions for Auto-Fill with Google Health Connect Integration

Health DX Progress Confirmation

This time, we will again identify the progress and challenges of Health DX tool users. Approximately one month has passed since the last session.

  • Weight: Continuing to decrease at a pace of 1kg per month. Progress is relatively steady.
  • Body Fat Percentage: The body composition monitor was switched midway, causing the readings to change.
  • Steps: Around 8,000 steps, with more days falling slightly below that.
  • Sleep: Continually getting less than 5 hours most nights, which is on the low side.

Last time, target values were set for each graph, and a moving average was added to the weight graph. This makes the targets easier to understand as benchmarks, and the moving average is also helping shift my mindset away from getting overly excited or disappointed by daily fluctuations.

Advantages and Challenges as a Health DX Tool

I will summarize the strengths and challenges based on my actual experience, including what was implemented in the previous initiative.

  • Positive Points
    • The improved usability of entering meals via buttons reduces the burden of daily input.
    • The target values on each graph provide clear daily benchmarks.
    • The addition of a weighted average for weight makes it easier to avoid getting overly excited or disappointed by daily fluctuations.
  • Challenges
    • Re-entering values already available on the smartphone (such as step count) is burdensome.

This time, I’ll continue making improvements in consultation with my trainer, but I’ll omit diet advice from Health DX. This is because progress has been relatively stable, and my trainer recommends continuing as is. This time, I’ll primarily focus on improving the tools.

Improving Health DX Tools

This time, we’ll consider improvements to “re-entering values already present on the smartphone.” For example, step counts and sleep duration are obtained by smartwatches or the smartphone itself, and on Android smartphones, they are accumulated in Google Health Connect. The functional structure is shown in the diagram.

I check the values in the Fitbit or Google Fit app, transcribe them into Appsheet, and ultimately record them in Google Spreadsheet via Appsheet. I want to reduce this transcription work. Specifically, I plan to develop a new app on my smartphone, as shown in the diagram below. This app will retrieve data from Health Connect and register the values in Spreadsheet via Google Apps Script.

This countermeasure involves establishing this countermeasure route. However, establishing this route presented significant challenges this time, so we have summarized the issues and countermeasures we encountered while leveraging generative AI to drive improvements.

The First Wall: Understanding build and dependency structures

This time, it was my first time developing an Android app (using Android Studio), my first time using Kotlin, and my first time using Gradle—a whole lot of firsts. While I’m using ChatGPT to help with the development, my lack of foundational knowledge was so severe that it took a considerable amount of time just to get the build working. I incorporated the generated source code and dependencies for accessing Health Connect into the simplest possible screen app in Android Studio, but I got stuck because it wouldn’t compile. The main issues were as follows:

  • Specifying SDK versions (compileSdk, targetSdk, minsdk)
  • Minimizing dependencies
  • Unsynchronized state due to not performing Gradle Sync

1.Specifying SDK Versions (compileSdk, targetSdk, minsdk)

The main source is MainActivity.kt, dependencies are specified in build.gradle.kts, and we build using Android Studio. We pass build errors to ChatGPT and iterate on improvements. The above two issues were resolved by specifying three SDK versions.

  • compilesdk = 36 # SDK version used during compilation
  • targetsdk = 34 # SDK version at runtime; slightly lower than compilesdk to resolve build errors
  • minsdk = 26 # Minimum guaranteed SDK version; specifies a version where Health Connect is available

Specifying the exact version was crucial. However, I didn’t thoroughly investigate the rationale behind each value. I had ChatGPT figure it out, and since the build wouldn’t pass, I ended up lowering the target SDK.

2.Streamline dependencies to the minimal configuration

This is also part of my trial and error with ChatGPT. It seems there was a conflict within the implementation that was included in the initially generated source code. When I tried passing the source to a different chat again, the results were narrowed down to the following two:

    implementation("androidx.health.connect:connect-client:1.1.0")
    implementation("com.squareup.okhttp3:okhttp:4.12.0")

The first line is the Health Connect library, and the second line is the library used to call Google Apps Script (GAS).

3.Unsynchronized State Due to Not Performing Gradle Sync

I hadn’t realized this due to my inexperience, but I assumed that updating the Gradle definitions would automatically keep dependencies up to date and load the necessary libraries. However, the “Gradle sync” operation was required.

In Android Studio, you can perform “Gradle sync” using the following screen operations:

  • Click the elephant icon labeled “Sync Project with Gradle Files” in the upper-right corner of the screen
  • or press “CTRL + SHIFT + O”

The Second Wall: Lack of Understanding of the Execution Environment and Permissions Model

This was partly due to my inexperience and reliance on generative AI, which led to gaps in my knowledge. The code generated by the AI didn’t run as-is; I had to modify it to resolve issues before it worked. I thought I understood this, but I still struggled quite a bit.

Specifically, when determining if Health Connect was active, I failed to notice that the meaning of the numbers differed depending on the SDK version. For a while, I mistakenly believed Health Connect wasn’t usable. Ultimately, the Health Connect check was implemented as follows:

val status = HealthConnectClient.getSdkStatus(this, HC_PROVIDER)
val statusLabel = when (status) {
    HealthConnectClient.SDK_AVAILABLE -> "SDK_AVAILABLE"
    HealthConnectClient.SDK_UNAVAILABLE -> "SDK_UNAVAILABLE"
    HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED -> "SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED"
    else -> "UNKNOWN($status)"
}
Log.d("HC", "Health Connect SDK status = $statusLabel ($status)")

This confirms that Health Connect is now available, allowing us to proceed.

The Third Wall: Asynchronous Processing and Network Design

There are many things you won’t notice unless you know about them. For example, there’s a rule stating that “Communication must not be an extension of button operations.” The initial source code generated by ChatGPT also treated it as communication extending from button operations. However, the issues mentioned above were pointed out, so I checked the countermeasures with ChatGPT and made improvements.

Specifically, I implemented the following three countermeasures:

  • Change post-processing to a suspend function
  • Wrap with withContext(Dispatchers.IO)
  • Add Coroutine import

It’s easy to write about, but I couldn’t solve it myself—it wouldn’t have improved without ChatGPT. I wish it had been designed to avoid problems from the start, but I’m satisfied that it’s resolved now.

Add Google Apps Script and update the spreadsheet

I also generated the source using AI and registered it. When I pointed out that Spreadsheet didn’t recognize the processing, they added it, and it executed surprisingly smoothly. The source is simple, with only about 20 to 30 lines.

Upon execution, values were recorded in column A (date) and column B (steps). Looking at column F, you can see that it was run twice over about four days. Each time, it aggregates and records data from the past three days.

Finally

I successfully connected to Health Connect and registered the data in Google Spreadsheets, but this data is actually incorrect. The numbers are significantly larger than the actual values, and I haven’t been able to capture weight, body fat percentage, or sleep duration, so further improvements are needed. I plan to address these issues in the next opportunity.

For now, I’ll consider it a success that I managed to punch holes in the series of processes and wrap things up here.

Leave a Reply

Your email address will not be published. Required fields are marked *