Reputation: 3105
I made an app that must be running in the background. The app basically register incoming calls and send timestamp to my server. Problem is that app is not working properly when it's killed after some time. I assume that OS simply kills my app however I don't know why.
Here's how I register my app in AndroidManifest.xml
file
<receiver
android:enabled="true"
android:name=".receiver.CallReceiver">
<intent-filter android:priority="99">
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
<intent-filter android:priority="100">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
And here's my CallReceiver
class CallReceiver: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// a lot of logic to send request using retrofit to my server
}
}
So problem is that after some time maybe (6-10 hours) App doesn't send any information to server. Why is it? After opening app again it starts to send data again.
Upvotes: 5
Views: 3215
Reputation: 1246
Here's my 2 cents:
Although NEW_OUTGOING_CALL is listed under
https://developer.android.com/guide/components/broadcast-exceptions,
your app is still considered background and is placed under strict conditions to execute. (They started doing that from Android-O).
Not sure if this is a bug or a feature, but it's Android, there're always some glitches to find.
This could be a device-specific issue, try on some other kind of device & android version?
Maybe you need to check this: https://stackoverflow.com/a/50110586/1562087
Upvotes: 0
Reputation: 657
After registering my BroadcastReceiver (BR) statically in the manifest, applying the proper intent filters, using JobIntentService (and registering it in the manifest) to handle the work that was called from my BR, I was still getting inconsistent results.
Once all of what I listed above has been done you should be able to send an ADB command to activate your broadcast and process the work in your service even if the app is closed. This was working for me some of the time, but not all of the time.
This article describes limitation to BRs. "As of Android 3.1 the Android system excludes all receiver from receiving intents by default if the corresponding application has never been started by the user or if the user explicitly stopped the application via the Android menu" (AKA a user executes Force Stop)
When I start the app by debugging it, then swipe it closed on my device (or when I end the debugging session in my IDE), my ADB command never activates my BR. However, after my debugging session is over, when I open up the app on my device and swipe it closed, I can activate my BR through ADB commands.
This occurs because when you debug an application, then manually swipe it closed on the device, Android considers this a Force Stop hence why my BR cannot be activated until I re-open the app on the device without debugging.
Scoured the internet for hours, and wasn't able to find my solution, so I thought I'd post it here just in case some poor unfortunate soul is encountering the same weird functionality I was.
Happy coding :)
Upvotes: 2
Reputation: 4442
Update:
From here
there is a timeout of 10 seconds that the system allows before considering the receiver to be blocked and a candidate to be killed
So, Broadcast receiver has a very low life expectancy (10 seconds). You might create a service for network calls.
Original:
From https://developer.android.com/guide/components/services
Note: If your app targets API level 26 or higher, the system imposes restrictions on running background services when the app itself isn't in the foreground.
So, if you want you service to survive on the background, you have to show a notification to make it a foreground service and thats why android wouldn't kill it.
another read, which states the same:
Prior to Android 8.0, the usual way to create a foreground service was to create a background service, then promote that service to the foreground. With Android 8.0, there is a complication; the system doesn't allow a background app to create a background service. For this reason, Android 8.0 introduces the new method startForegroundService() to start a new service in the foreground. After the system has created the service, the app has five seconds to call the service's startForeground() method to show the new service's user-visible notification. If the app does not call startForeground() within the time limit, the system stops the service and declares the app to be ANR.
source :https://developer.android.com/about/versions/oreo/background
Upvotes: 1