如何解决Android 睡眠 Api 异常:com.google.android.gms.common.api.ApiException:16:
我正在尝试运行 android 团队提供的 Sleep Sample 应用程序来展示新 Sleep API 的使用。 该应用程序在某些设备(OnePlus、Pixel、诺基亚)上运行良好,但在某些设备(三星)上显示错误“com.google.android.gms.common.api.ApiException: 16:”。我认为这必须与 Google Play 服务有关,所以我已经更新了它。我的手机运行的是三星 Color OS 和 Android 11。它具有最新版本的 GooglePlay 和 Google Play 服务。这个问题往往只发生在三星设备上(在我测试过的设备中)
package com.android.example.sleepcodelab
import android.Manifest.permission
import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.android.example.sleepcodelab.databinding.ActivityMainBinding
import com.android.example.sleepcodelab.receiver.SleepReceiver
import com.google.android.gms.location.ActivityRecognition
import com.google.android.gms.location.SleepSegmentRequest
import com.google.android.material.snackbar.Snackbar
import java.util.Calendar
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val mainViewModel: MainViewModel by lazy {
MainViewModel((application as MainApplication).repository)
}
private var sleepSegmentOutput: String = ""
private var sleepClassifyOutput: String = ""
private var subscribedToSleepData = false
set(newSubscribedToSleepData) {
field = newSubscribedToSleepData
if (newSubscribedToSleepData) {
binding.button.text = getString(R.string.sleep_button_unsubscribe_text)
} else {
binding.button.text = getString(R.string.sleep_button_subscribe_text)
}
updateOutput()
}
private lateinit var sleepPendingIntent: PendingIntent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
mainViewModel.subscribedToSleepDataLiveData.observe(this) { newSubscribedToSleepData ->
if (subscribedToSleepData != newSubscribedToSleepData) {
subscribedToSleepData = newSubscribedToSleepData
}
}
mainViewModel.allSleepSegments.observe(this) { sleepSegmentEventEntities ->
Log.d(TAG,"sleepSegmentEventEntities: $sleepSegmentEventEntities")
if (sleepSegmentEventEntities.isNotEmpty()) {
sleepSegmentOutput = sleepSegmentEventEntities.joinToString {
"\t$it\n"
}
updateOutput()
}
}
mainViewModel.allSleepClassifyEventEntities.observe(this) {
sleepClassifyEventEntities ->
Log.d(TAG,"sleepClassifyEventEntities: $sleepClassifyEventEntities")
if (sleepClassifyEventEntities.isNotEmpty()) {
sleepClassifyOutput = sleepClassifyEventEntities.joinToString {
"\t$it\n"
}
updateOutput()
}
}
sleepPendingIntent =
SleepReceiver.createSleepReceiverPendingIntent(context = applicationContext)
}
fun onClickRequestSleepData(view: View) {
if (activityRecognitionPermissionApproved()) {
if (subscribedToSleepData) {
unsubscribeToSleepSegmentUpdates(applicationContext,sleepPendingIntent)
} else {
subscribeToSleepSegmentUpdates(applicationContext,sleepPendingIntent)
}
} else {
requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION)
}
}
@SuppressLint("MissingPermission")
private fun subscribeToSleepSegmentUpdates(context: Context,pendingIntent: PendingIntent) {
Log.d(TAG,"requestSleepSegmentUpdates()")
val task = ActivityRecognition.getClient(context).requestSleepSegmentUpdates(
pendingIntent,SleepSegmentRequest.getDefaultSleepSegmentRequest()
)
task.addOnSuccessListener {
mainViewModel.updateSubscribedToSleepData(true)
Log.d(TAG,"Successfully subscribed to sleep data.")
}
task.addOnFailureListener { exception ->
Log.d(TAG,"Exception when subscribing to sleep data: $exception")
}
}
private fun unsubscribeToSleepSegmentUpdates(context: Context,"unsubscribeToSleepSegmentUpdates()")
val task = ActivityRecognition.getClient(context).removeSleepSegmentUpdates(pendingIntent)
task.addOnSuccessListener {
mainViewModel.updateSubscribedToSleepData(false)
Log.d(TAG,"Successfully unsubscribed to sleep data.")
}
task.addOnFailureListener { exception ->
Log.d(TAG,"Exception when unsubscribing to sleep data: $exception")
}
}
private fun activityRecognitionPermissionApproved(): Boolean {
return PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(
this,permission.ACTIVITY_RECOGNITION
)
}
private val requestPermissionLauncher: ActivityResultLauncher<String> =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (!isGranted) {
displayPermissionSettingsSnackBar()
} else {
binding.outputTextView.text = getString(R.string.permission_approved)
}
}
private fun displayPermissionSettingsSnackBar() {
Snackbar.make(
binding.mainActivity,R.string.permission_rational,Snackbar.LENGTH_LONG
)
.setAction(R.string.action_settings) {
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
val uri = Uri.fromParts(
"package",BuildConfig.APPLICATION_ID,null
)
intent.data = uri
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
.show()
}
private fun updateOutput() {
Log.d(TAG,"updateOutput()")
val header = if (subscribedToSleepData) {
val timestamp = Calendar.getInstance().time.toString()
getString(R.string.main_output_header1_subscribed_sleep_data,timestamp)
} else {
getString(R.string.main_output_header1_unsubscribed_sleep_data)
}
val sleepData = getString(
R.string.main_output_header2_and_sleep_data,sleepSegmentOutput,sleepClassifyOutput
)
val newOutput = header + sleepData
binding.outputTextView.text = newOutput
}
companion object {
private const val TAG = "MainActivity"
}
}
每当我点击订阅睡眠数据按钮时,它都会在 logcat 中出现“订阅睡眠数据时出现异常:com.google.android.gms.common.api.ApiException: 16:”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。