Since android 8 the OS has placed may restrictions on how and when can the apps use Broadcast Receivers and Services.
TL;DR: Starting Android 8 the OS will stop your Services and Broadcast Receivers except in some situations mentioned in above documents.
What is then a proper way to detect incoming sms? We can use WorkManager to manually query the SMS to check for new entries every 15 minutes. But what would be a way to get it instantly?
Also the official docs list the SMS_RECEIVE
intent in the list of broadcasts that are exceptions to the above rules, but many have found that the receivers and services still get terminated and I have confirmed that by testing it myself.
There are some spend tracking apps out there that still do track the incoming sms regardless of the situation.
Would appreciate any inputs on the situation.
Thanks.
Probably it is too late to answer for the OP, but in case someone else lands here like me, turns out you can now use WorkManager
to get notified for new SMS. You would do something like this,
class ProcessNewSmsWorker(
appContext: Context,
params: WorkerParameters
) : CoroutineWorker(appContext, params) {
private lateinit var workManager: WorkManager
override suspend fun doWork(): Result {
// Get SMS from ContentResolver and process them as needed
// Enqueue again to process new changes in Sms.Sms.CONTENT_URI since last SMS DB read
doEnqueueWorkerToUploadNewMessages(workManager)
return Result.success()
}
companion object {
val TAG: String = ProcessNewSmsWorker::class.java.simpleName
private val constraints: Constraints by lazy {
Constraints.Builder()
.addContentUriTrigger(Sms.CONTENT_URI, true)
.setTriggerContentMaxDelay(3, TimeUnit.SECONDS)
.setTriggerContentUpdateDelay(3, TimeUnit.SECONDS)
.build()
}
fun doEnqueueWorkerToUploadNewMessages(workManager: WorkManager) {
workManager.enqueueUniqueWork(
TAG,
// NOTE: APPEND isn't triggering the worker at all
ExistingWorkPolicy.APPEND_OR_REPLACE,
OneTimeWorkRequestBuilder<ProcessNewSmsWorker>()
.addTag(TAG)
.setConstraints(constraints)
.build()
)
}
}
}
You can call the fun doEnqueueWorkerToUploadNewMessages()
from the Application class to enqueue this worker at app start up
Hope this help!