You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

三星健康Data SDK调用getGrantedPermissions或requestPermissions时触发AuthorizationException: 2003问题求助

三星健康Data SDK调用getGrantedPermissions或requestPermissions时触发AuthorizationException: 2003问题求助

大家好,我最近在开发一款教育类Android应用,想要集成三星健康App来获取心率这类生物医学数据,结果卡在了权限环节——每次调用HealthDataStore.getGrantedPermissions()或者HealthDataStore.requestPermissions()都会抛出AuthorizationException(错误码2003),试了好几种方法都没解决,来求助各位大佬!

环境信息

  • 设备:Poco F3,Android 13(已开启开发者模式)
  • 使用的SDK:samsung-health-data-api-1.0.0-b2.aar

实现逻辑

我封装了SamsungHealthRepository类来处理和三星健康Data SDK的交互,这个类由BiodataViewModel调用。核心问题出在processPermissions()方法里,每次执行权限检查或请求的步骤就会触发异常。

相关代码

SamsungHealthRepository.kt

package com.slowdive.biodata.data

import android.app.Activity
import android.content.Context
import android.health.connect.HealthPermissions
import android.util.Log
import com.samsung.android.sdk.health.data.HealthDataService
import com.samsung.android.sdk.health.data.data.HealthDataPoint
import com.samsung.android.sdk.health.data.error.ResolvablePlatformException
import com.samsung.android.sdk.health.data.permission.AccessType
import com.samsung.android.sdk.health.data.permission.Permission
import com.samsung.android.sdk.health.data.request.DataType
import com.samsung.android.sdk.health.data.request.DataTypes
import com.samsung.android.sdk.health.data.request.LocalTimeFilter
import com.samsung.android.sdk.health.data.request.Ordering
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.time.LocalDateTime
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Repository for interacting with Samsung Health API
 */
@Singleton
class SamsungHealthRepository @Inject constructor(private val context: Context) {
    private val TAG = "SamsungHealthRepository"

    suspend fun getLatestHeartRate(): Int? {
        return withContext(Dispatchers.IO) {
            try {
                processPermissions()
                val now = LocalDateTime.now()
                val oneDayAgo = now.minusDays(1)
                val localTimeFilter = LocalTimeFilter.of(oneDayAgo, now)
                val readRequest = DataTypes.HEART_RATE.readDataRequestBuilder
                    .setLocalTimeFilter(localTimeFilter)
                    .setOrdering(Ordering.DESC)
                    .setLimit(1)
                    .build()
                val healthDataStore = HealthDataService.getStore(context)
                val heartRateList = healthDataStore.readData(readRequest).dataList
                if (heartRateList.isNotEmpty()) {
                    val latestHeartRate = processHeartRateData(heartRateList.first())
                    Log.d(TAG, "Latest heart rate: $latestHeartRate")
                    return@withContext latestHeartRate
                } else {
                    Log.d(TAG, "No heart rate data found in the last 24 hours")
                    return@withContext null
                }
            } catch (e: Exception) {
                Log.e(TAG, "Error reading heart rate data: ${e}")
                return@withContext null
            }
        }
    }

    private suspend fun processPermissions(): Boolean {
        return withContext(Dispatchers.IO) {
            try {
                val healthDataStore = HealthDataService.getStore(context);
                val permissionsNeeded = mutableSetOf(Permission.of(DataTypes.HEART_RATE, AccessType.READ))
                val grantedPermissions = healthDataStore.getGrantedPermissions(permissionsNeeded)
                if (!grantedPermissions.containsAll(permissionsNeeded)) {
                    val result = healthDataStore.requestPermissions(permissionsNeeded, context as Activity)
                    return@withContext result.containsAll(permissionsNeeded)
                }
                return@withContext true
            } catch (error: Exception) {
                if (error is ResolvablePlatformException && error.hasResolution) {
                    error.resolve(context as Activity)
                    return@withContext false
                }
                return@withContext false
            }
        }
    }

    private fun processHeartRateData(heartRateData: HealthDataPoint): Int? {
        return heartRateData.getValue(DataType.HeartRateType.HEART_RATE)?.toInt()
    }
}

BiodataViewModel.kt

package com.slowdive.biodata.presentation

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.slowdive.SlowdiveApplication
import com.slowdive.biodata.data.SamsungHealthRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * ViewModel for the Biodata screen that handles biomedical data
 */
@HiltViewModel
class BiodataViewModel @Inject constructor(
    private val samsungHealthRepository: SamsungHealthRepository
) : ViewModel() {
    private val _heartRate = MutableStateFlow(40)
    val heartRate: StateFlow<Int> = _heartRate

    private val _stressLevel = MutableStateFlow(0.4f)
    val stressLevel: StateFlow<Float> = _stressLevel

    private val _bloodOxygenLevel = MutableStateFlow(98)
    val bloodOxygenLevel: StateFlow<Int> = _bloodOxygenLevel

    /**
     * Sync biodata from Samsung Health
     */
    fun syncBiodata() {
        viewModelScope.launch {
            try {
                val heartRateValue = samsungHealthRepository.getLatestHeartRate()
                heartRateValue?.let {
                    _heartRate.value = heartRateValue
                }
            } catch (e: Exception) {
                Log.e(SlowdiveApplication.APP_TAG, "Error syncing biodata: ${e.message}")
            }
        }
    }
}

已排查的点

  • 设备已开启开发者模式
  • 三星健康App已正常安装并登录账号
  • AndroidManifest中已添加android.permission.health.READ_HEART_RATE权限

实在找不到问题所在,有没有大佬能指点一下?感激不尽!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 12:12:59