Search code examples
androidbroadcastreceiverandroid-8.0-oreobackground-servicejobintentservice

SMS_RECEIVED Broadcast Receiver and JobIntentService in Oreo


I have read the Android documentation regarding the new background restrictions in Android API Level 26, and with those in mind, I have designed my app as follows:

  • The app has a BroadcastReceiver listening for the "SMS_RECEIVED" broadcast. This is an implicit broadcast, which are now restricted in Oreo, however it is one of those in their exceptions list.
  • When this BroadcastReceiver runs, it enqueues a new task to be performed by a JobIntentService. When receiving the broadcast, the app should be temporarily whitelisted and therefore, the JobIntentService given a window of opportunity to do its thing.

All of this seems to be working just fine, even if I close the app from the "recent apps" list. However, I'm getting reports from some users that apparently every few days, they have to open the app again because it suddenly stops working in the background.

Why does the OS suddenly stop sending the "SMS_RECEIVED" broadcast to my app? If it is not that, then it must be the JobIntentService not being allowed to run. Why not? The app should be whitelisted immediately after receiving the SMS. What am I misunderstanding?


Solution

  • Besides Doze, Android also contains functionality called App Standby. As per the documentation:

    App Standby defers background network activity for apps with which the user has not recently interacted.

    The default 'recently interacted' time frame is 3 days, which corresponds with your reports of things stopping 'apparently every few days'.

    Therefore what seems to be happening is your JobIntentService fires (your app is indeed still whitelisted after receiving the broadcast), but App Standby is preventing your JobIntentService from connecting to the network.

    You can confirm this is the case by following the Testing your app with App Standby instructions:

    adb shell dumpsys battery unplug
    adb shell am set-inactive <packageName> true
    

    You might consider looking through the Acceptable use cases for whitelisting to see if asking to ignore battery optimizations is an option for your use case.