如何从Health Connect读取运动GPS轨迹?Kotlin开发疑难
从Health Connect获取GPS轨迹数据的问题
问题背景
我正在Android Studio中开发Kotlin项目,需要从Health Connect获取GPS轨迹的经纬度数据,用来生成运动的「最快时段」列表。已经把Fitbit步行数据同步到了Health Connect,但目前卡在获取经纬度这一步。
已实现的代码
我已经能读取过去一个月的所有ExerciseSessionRecord:
val request = ReadRecordsRequest( recordType = ExerciseSessionRecord::class, timeRangeFilter = TimeRangeFilter.between(from, to) ) val response = healthConnectClient.readRecords(request)
遇到的核心问题
- Health Connect提供的Record类型里没有
LocationRecord,现有的类型包括CervicalMucusRecord、SexualActivityRecord等 ExerciseSessionRecord的结构里不包含经纬度信息,其结构如下:
ExerciseSessionRecord( startTime: Instant, startZoneOffset: ZoneOffset?, endTime: Instant, endZoneOffset: ZoneOffset?, exerciseType: Int, title: String?, notes: String?, metadata: Metadata )
测试代码及日志
MainActivity代码
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val permissionsLauncher = PermissionController.createRequestPermissionResultContract() val permissions = setOf( HealthPermission.getReadPermission(ExerciseSessionRecord::class) ) var sessionsList: MutableState<List<ExerciseSessionRecord>> = mutableStateOf(listOf()) // Catch the result from the system's permissions dialog val requestPermissions = registerForActivityResult(permissionsLauncher) { granted -> if (granted.containsAll(permissions)) { // Permissions successfully granted // PERMISSIONS: Set<string> as of Alpha11 Log.d(TAG, "MainActivity: Permissions granted: $granted") syncJob.cancel(CancellationException("Permissions have changed. Try again.")) } else { Log.d(TAG, "MainActivity: Lack of permissions") } } // Check for permissions suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) { // For alpha09 and lower versions, use getGrantedPermissions(PERMISSIONS) instead val granted = healthConnectClient.permissionController.getGrantedPermissions() if (granted.containsAll(permissions)) { // Permissions already granted; proceed with inserting or reading data. Log.d(TAG, "MainActivity: Permissions have already been granted") val now = Instant.now() val request = ReadRecordsRequest( recordType = ExerciseSessionRecord::class, timeRangeFilter = TimeRangeFilter.between(now.minusSeconds(2592000), now) ) val response = healthConnectClient.readRecords(request) sessionsList.value = response.records } else { // Launch system dialog to select permissions requestPermissions.launch(permissions) } } // Health Connect Button buttonHealthConnect.setOnClickListener(View.OnClickListener { progressBarFragment.visibility = View.VISIBLE initSyncJob() val context = this CoroutineScope(IO + syncJob).launch { delay(2000) if(isSDKAvailable()) { val healthConnectClient = HealthConnectClient.getOrCreate(context) checkPermissionsAndRun(healthConnectClient) var result = "" var type = "" for(value in sessionsList.value){ Log.d(TAG, "MainActivity type = ${value.exerciseType}") type = when (value.exerciseType) { 8 -> "Cycling" 79 -> "Walking" else -> "Other" } result = result.plus("${type}: ${value.startTime}\n") } textViewResults.setText(result) Log.d(TAG, "MainActivity: \nReturned data from Health Connect: \n$result") syncJob.complete() } else { syncJob.cancel(CancellationException("Cancelled: SDK unavailable")) } } }) }
AndroidManifest代码
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.zoomzoom.fitnessappstest"> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.FitnessAppsTest" tools:targetApi="31"> <activity android:name="com.fitnessappstest.ui.MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <!-- Required to specify which Health Connect permissions the app can request --> <uses-permission android:name="android.permission.health.READ_EXERCISE" /> <queries> <!-- Declare Health Connect visibility --> <package android:name="com.google.android.apps.healthdata" /> </queries> </manifest>
Logcat输出
[-- Clicked Health Connect Button --] MainActivity: SDK is available MainActivity: Returned data from Health Connect: MainActivity: syncJob complete [-- Approved permissions in permissionLauncher --] Permissions granted: [android.permission.health.READ_EXERCISE] MainActivity: SDK is available MainActivity: Permissions have already been granted MainActivity type = 8 MainActivity type = 8 MainActivity type = 79 MainActivity type = 79 MainActivity: Returned data from Health Connect: Cycling: 2023-05-12T23:53:15.670Z Cycling: 2023-05-18T01:30:27.710Z Walking: 2023-06-09T04:30:50.131Z Walking: 2023-06-09T04:33:37.100Z MainActivity: syncJob complete
补充说明
选择Health Connect的原因:
- Google Fitness API将于2024年停用
- Samsung Health API不再审核新应用
- Garmin Connect需要审核,暂未深入了解
内容的提问来源于stack exchange,提问作者beebopbogo
相关产品推荐
相关产品推荐

