androidsmsbackground-processbackground-service

Receiving Incoming SMS post Android 8


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.


Solution

  • 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!