I am trying to run the Sleep Sample app provided by the android team to showcase the use of the new Sleep API. The app runs fine on some devices(OnePlus, Pixel, Nokia) but shows the error "com.google.android.gms.common.api.ApiException: 16:" on some devices(Samsung). I thought this had to do something with Google Play Services So I already updated it. My phone is running Samsung Color OS with Android 11. It has the latest version of GooglePlay and Google Play services. This problem tends to occur only on Samsung devices(Among the devices I have tested this on)
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, pendingIntent: PendingIntent) {
Log.d(TAG, "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"
}
}
Whenever I click on subscribe to sleep data button, it has " Exception when subscribing to sleep data: com.google.android.gms.common.api.ApiException: 16: " in logcat.

