尝试访问 Google Fit API 时出现异常 - 用户必须登录才能进行此 API 调用

Rau*_*Acu 13 android kotlin google-fit wear-os google-fit-api

我正在尝试设置一个在 WearOS 上运行的可穿戴应用程序(适用于华为 Watch 2),以将心率 (BPM) 持续提供到 Google Fit 帐户中,该帐户会被读入另一个智能手机应用程序中。

当我尝试设置帐户并访问数据时出现问题,如下所示:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS)
        != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.BODY_SENSORS),GOOGLE_FIT_PERMISSIONS_REQUEST_CODE)
}

fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
.build()

account = GoogleSignIn.getAccountForExtension(this, fitnessOptions)
if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
    GoogleSignIn.requestPermissions(
        this, // your activity
        GOOGLE_FIT_PERMISSIONS_REQUEST_CODE, // e.g. 1
        account,
        fitnessOptions);
} else {
    accessGoogleFit()
}
timer.scheduleAtFixedRate(
    object : TimerTask() {
        override fun run() {
            Log.i("[TimerTask]", "Retrieving data..")
            accessGoogleFit()
            Log.i("[Account]", "" + account.email)

        }
    },0, 1000
)
    // Enables Always-on
setAmbientEnabled()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (resultCode) {
        Activity.RESULT_OK -> when (requestCode) {
            GOOGLE_FIT_PERMISSIONS_REQUEST_CODE -> accessGoogleFit()
            else -> {}
        }
        else -> {}
    }
}

private fun accessGoogleFit() {
    val cal: Calendar = Calendar.getInstance()
    val now = Date()
    cal.setTime(now)
    val endTime: Long = cal.getTimeInMillis()
    cal.add(Calendar.DAY_OF_MONTH, -1)
    val startTime: Long = cal.getTimeInMillis()

    val historyRequest = DataReadRequest.Builder()
    .read(DataType.TYPE_HEART_RATE_BPM)
    .enableServerQueries()
    .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
    .build()
    val sourceRequest = DataSourcesRequest.Builder()
    .setDataTypes(DataType.TYPE_HEART_RATE_BPM)
    .setDataSourceTypes(DataSource.TYPE_RAW, DataSource.TYPE_DERIVED)
    .build()

    Fitness.getHistoryClient(this,account)
    .readData(historyRequest)
    .addOnSuccessListener{
        response-> txt_GoogleFit_FitData.setText(response.dataSets.get(0).toString())
    }
    .addOnFailureListener{ e ->
    Log.e("[GoogleFIT]", "Find data sources request failed", e)
}

Fitness.getSensorsClient(this, account)
.findDataSources(sourceRequest)
.addOnSuccessListener { dataSources ->
dataSources.forEach {
    Log.i("[GoogleFIT]", "Data source found: ${it.streamIdentifier}")
    Log.i("[GoogleFIT]", "Data Source type: ${it.dataType.name}")

    if (it.dataType == DataType.TYPE_HEART_RATE_BPM) {
        Log.i("[GoogleFIT]", "Data source for LOCATION_SAMPLE found!")
    }
}
}
.addOnFailureListener { e ->
Log.e("[GoogleFIT]", "Find data sources request failed", e)
}
}
Run Code Online (Sandbox Code Playgroud)

异常的堆栈跟踪:

2021-01-27 17:08:07.032 13743-13767/com.example.watch_bpmupdated2 I/[TimerTask]: Retrieving data..
2021-01-27 17:08:07.036 13743-13767/com.example.watch_bpmupdated2 I/[Account]: <<default account>>
2021-01-27 17:08:07.057 13743-13743/com.example.watch_bpmupdated2 E/[GoogleFIT]: Find data sources request failed
    com.google.android.gms.common.api.ApiException: 4: The user must be signed in to make this API call.
        at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base@@17.1.0:4)
        at com.google.android.gms.common.internal.zai.zaf(com.google.android.gms:play-services-base@@17.1.0:2)
        at com.google.android.gms.common.internal.zak.onComplete(com.google.android.gms:play-services-base@@17.1.0:6)
        at com.google.android.gms.common.api.internal.BasePendingResult.zaa(com.google.android.gms:play-services-base@@17.1.0:176)
        at com.google.android.gms.common.api.internal.BasePendingResult.setResult(com.google.android.gms:play-services-base@@17.1.0:135)
        at com.google.android.gms.common.api.internal.BaseImplementation$ApiMethodImpl.setFailedResult(com.google.android.gms:play-services-base@@17.1.0:29)
        at com.google.android.gms.common.api.internal.zad.zaa(com.google.android.gms:play-services-base@@17.1.0:9)
        at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zac(com.google.android.gms:play-services-base@@17.1.0:175)
        at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.onConnectionFailed(com.google.android.gms:play-services-base@@17.1.0:79)
        at com.google.android.gms.common.internal.zag.onConnectionFailed(com.google.android.gms:play-services-base@@17.1.0:2)
        at com.google.android.gms.common.internal.BaseGmsClient$zzg.zza(com.google.android.gms:play-services-basement@@17.1.1:6)
        at com.google.android.gms.common.internal.BaseGmsClient$zza.zza(com.google.android.gms:play-services-basement@@17.1.1:25)
        at com.google.android.gms.common.internal.BaseGmsClient$zzb.zzo(com.google.android.gms:play-services-basement@@17.1.1:11)
        at com.google.android.gms.common.internal.BaseGmsClient$zzc.handleMessage(com.google.android.gms:play-services-basement@@17.1.1:49)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at com.google.android.gms.internal.common.zzi.dispatchMessage(com.google.android.gms:play-services-basement@@17.1.1:8)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)
2021-01-27 17:08:07.060 13743-13743/com.example.watch_bpmupdated2 E/[GoogleFIT]: Find data sources request failed
    com.google.android.gms.common.api.ApiException: 4: The user must be signed in to make this API call.
        at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base@@17.1.0:4)
        at com.google.android.gms.common.internal.zai.zaf(com.google.android.gms:play-services-base@@17.1.0:2)
        at com.google.android.gms.common.internal.zak.onComplete(com.google.android.gms:play-services-base@@17.1.0:6)
        at com.google.android.gms.common.api.internal.BasePendingResult.zaa(com.google.android.gms:play-services-base@@17.1.0:176)
        at com.google.android.gms.common.api.internal.BasePendingResult.setResult(com.google.android.gms:play-services-base@@17.1.0:135)
        at com.google.android.gms.common.api.internal.BaseImplementation$ApiMethodImpl.setFailedResult(com.google.android.gms:play-services-base@@17.1.0:29)
        at com.google.android.gms.common.api.internal.zad.zaa(com.google.android.gms:play-services-base@@17.1.0:9)
        at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zac(com.google.android.gms:play-services-base@@17.1.0:175)
        at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.onConnectionFailed(com.google.android.gms:play-services-base@@17.1.0:79)
        at com.google.android.gms.common.internal.zag.onConnectionFailed(com.google.android.gms:play-services-base@@17.1.0:2)
        at com.google.android.gms.common.internal.BaseGmsClient$zzg.zza(com.google.android.gms:play-services-basement@@17.1.1:6)
        at com.google.android.gms.common.internal.BaseGmsClient$zza.zza(com.google.android.gms:play-services-basement@@17.1.1:25)
        at com.google.android.gms.common.internal.BaseGmsClient$zzb.zzo(com.google.android.gms:play-services-basement@@17.1.1:11)
        at com.google.android.gms.common.internal.BaseGmsClient$zzc.handleMessage(com.google.android.gms:play-services-basement@@17.1.1:49)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at com.google.android.gms.internal.common.zzi.dispatchMessage(com.google.android.gms:play-services-basement@@17.1.1:8)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)
Run Code Online (Sandbox Code Playgroud)

我的手表与我用来读取数据的智能手机配对(我只需要来自 google fit 的更快更新,并考虑强制执行此操作。此处不提供代码)。存在相同的 Google Fit 帐户,登录 Google Fit 应用程序并在两台设备上同步。一切在智能手机上运行顺利(即使使用相同的代码),而在手表上,我在设置帐户时遇到“用户必须登录”异常。

Google 服务依赖项、应用程序权限在两台设备上的设置方式相同,以及开发人员控制台上所需的 OAuth 设置、SHA1 和凭据。

这可能是与手表->应用程序->Google Fit 帐户同步相关的问题,还是我遗漏了什么?

Dim*_*ams 2

在为您的项目添加 OAuth 2.0 客户端 ID 后,在 Google Console 中注册项目并添加您的 Google 帐户作为测试用户。

这应该可以解决登录问题。