Getting started: Android configuration
Prepare your project for Health Connect.
Android configuration
In your build.gradle (app) set your min and target sdk version like below:
minSdk 26
targetSdk 34
Included permissions
This SDK will use the following permissions, there is no need to declare them in your manifest as the rook_sdk_health_connect already declares them in its own manifest:
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_HEALTH"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.health.READ_SLEEP"/>
<uses-permission android:name="android.permission.health.READ_STEPS"/>
<uses-permission android:name="android.permission.health.READ_DISTANCE"/>
<uses-permission android:name="android.permission.health.READ_FLOORS_CLIMBED"/>
<uses-permission android:name="android.permission.health.READ_ELEVATION_GAINED"/>
<uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"/>
<uses-permission android:name="android.permission.health.READ_VO2_MAX"/>
<uses-permission android:name="android.permission.health.READ_TOTAL_CALORIES_BURNED"/>
<uses-permission android:name="android.permission.health.READ_ACTIVE_CALORIES_BURNED"/>
<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
<uses-permission android:name="android.permission.health.READ_RESTING_HEART_RATE"/>
<uses-permission android:name="android.permission.health.READ_HEART_RATE_VARIABILITY"/>
<uses-permission android:name="android.permission.health.READ_EXERCISE"/>
<uses-permission android:name="android.permission.health.READ_SPEED"/>
<uses-permission android:name="android.permission.health.READ_WEIGHT"/>
<uses-permission android:name="android.permission.health.READ_HEIGHT"/>
<uses-permission android:name="android.permission.health.READ_BLOOD_GLUCOSE"/>
<uses-permission android:name="android.permission.health.READ_BLOOD_PRESSURE"/>
<uses-permission android:name="android.permission.health.READ_HYDRATION"/>
<uses-permission android:name="android.permission.health.READ_BODY_TEMPERATURE"/>
<uses-permission android:name="android.permission.health.READ_RESPIRATORY_RATE"/>
<uses-permission android:name="android.permission.health.READ_NUTRITION"/>
<uses-permission android:name="android.permission.health.READ_MENSTRUATION"/>
<uses-permission android:name="android.permission.health.READ_POWER"/>
Google may require you to provide an explanation about the FOREGROUND_SERVICE
/FOREGROUND_SERVICE_HEALTH
permissions,
these permissions are used by our Automatic Sync
and Background Steps features, to extract health data and upload it to ROOK servers. We
recommend you to ask users for permission before enabling these features (Google may also require a video proof of a
screen where a user can turn on/off these features).
Obfuscation
If you are using obfuscation consider the following:
In the app folder create a proguard-rules.pro file and add the following:
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
-keep class com.google.crypto.** { *; }
Finally, in your build.gradle (app) add the proguard-rules.pro
from previous step:
buildTypes {
release {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
In your gradle.properties (Project level) add the following to disable R8 full mode:
android.enableR8.fullMode=false
If you want to enable full mode add the following rules to proguard-rules.pro:
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# Protobuf
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
# Crypto
-keep class com.google.crypto.** { *; }
Privacy policy
Health Connect requires a privacy policy where you inform your users how you will handle and use their data.
To comply with this you'll need an intent filter, inside your MainActivity declaration add an intent filter for the Health Connect permissions action:
<application>
<activity android:name=".MainActivity">
<!-- For supported versions through Android 13, create an activity to show the rationale
of Health Connect permissions once users click the privacy policy link. -->
<intent-filter>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
</intent-filter>
</activity>
<!-- For versions starting Android 14, create an activity alias to show the rationale
of Health Connect permissions once users click the privacy policy link. -->
<activity-alias
android:name="ViewPermissionUsageActivity"
android:exported="true"
android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
<category android:name="android.intent.category.HEALTH_PERMISSIONS"/>
</intent-filter>
</activity-alias>
</application>
Finally, to listen when your app is launched from said intent, you can code your own implementation from scratch or use a package like receive_intent. You can find an example of the second approach in our demo app.
Request data access
When you are developing with the Health Connect SDK data access is unrestricted. In order to have data access when your app is launched to the PlayStore you MUST complete the Developer Declaration Form, more information Here.
When you are asked about what data types is your app using please add the following data types as READ access:
- ActiveCaloriesBurnedRecord
- BloodGlucoseRecord
- BloodPressureRecord
- BodyTemperatureRecord
- DistanceRecord
- ElevationGainedRecord
- ExerciseSessionRecord
- FloorsClimbedRecord
- HeartRateRecord
- HeartRateVariabilityRmssdRecord
- HeightRecord
- HydrationRecord
- MenstruationPeriodRecord
- NutritionRecord
- OxygenSaturationRecord
- PowerRecord
- RespiratoryRateRecord
- RestingHeartRateRecord
- SleepSessionRecord
- SpeedRecord
- StepsCadenceRecord
- StepsRecord
- TotalCaloriesBurnedRecord
- Vo2MaxRecord
- WeightRecord
Secure storage (optional)
This SDK saves sensitive information like current logged user in a password protected storage, you can specify a file name (without extension) and the password used to access it with two meta-data tags in your manifest:
This configuration is completely optional if you don't provide the two following tags the SDK will use a default file name and auto-generate a new password every time your app is installed or it's data is deleted.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<!--
PLEASE NOTE THAT BOTH TAGS ARE REQUIRED
IF YOU EVER LOSE THE PASSWORD THE SDK WILL BECOME UNABLE TO PERFORM ITS FUNCTIONS
YOU CAN CHANGE THE NAME OF THE STORAGE TO FIX IT, BUT ALL PREVIOUS DATA WILL BE LOST.
-->
<meta-data
android:name="io.tryrook.security.storage.FILE_NAME"
android:value="secure_storage"/>
<meta-data
android:name="io.tryrook.security.storage.PASSWORD"
android:value="my_super_secret_password"/>
</application>
</manifest>
Completed AndroidManifest
At the end your AndroidManifest.xml should look like:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:label="F-Rook Mono">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- For supported versions through Android 13, create an activity to show the rationale
of Health Connect permissions once users click the privacy policy link. -->
<intent-filter>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE"/>
</intent-filter>
</activity>
<!-- For versions starting Android 14, create an activity alias to show the rationale
of Health Connect permissions once users click the privacy policy link. -->
<activity-alias
android:name="ViewPermissionUsageActivity"
android:exported="true"
android:permission="android.permission.START_VIEW_PERMISSION_USAGE"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
<category android:name="android.intent.category.HEALTH_PERMISSIONS"/>
</intent-filter>
</activity-alias>
<meta-data
android:name="flutterEmbedding"
android:value="2"/>
</application>
</manifest>