Now that the final API for Android O is released and none of the following broadcasts is whitelisted I have the following problem:
In my application (targets API 25) I currently have a BroadcastReceiver which listens for system events of ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED. Now I would like to update my app to target Android O but with this release comes a huge change in broadcast behaviors:
Apps that target Android O can no longer register broadcast receivers
for implicit broadcasts in their manifest. An implicit broadcast is a
broadcast that does not target that app specifically.
Since both broadcasts are implicit I can only register for them via the Context.registerReceiver() method but with this comes the problem: As soon as the process of my app is killed by the system or as soon as system clears my app's memory (as a result of low-memory of device) the broadcast registration will be lost.
To avoid this problem I can use the JobScheduler API with the setRequiresCharging method for ACTION_POWER_CONNECTED but for ACTION_POWER_DISCONNECTED I have to use the registerReceiver method.
Since my app controls the volume of the device (based on these events) it's really important that none of these events is missed. So how can I safely listen for disconnected power events in Android O?
Btw. I have the same problem with WIFI disconnect events.
EDIT: I would love to do this without a notification from a foreground service
Jobs can be delayed without any constraint by the system. The setOverrideDeadline method uses just a best-effort policy, so in this case you can keep your target SDK to 25 or use a foreground service. Foregournd services can be killed by the system but with really low probability.
This may be overkill, but you could register for those broadcasts in a foreground Service that is started by ACTION_BOOT_COMPLETED.
You can register a background job with the JobScheduler using the "requires charging" constraint. At least this is the official solution suggestion.
Related
in my app I use 3 broadcast receivers for the following broadcasts:
android.net.wifi.STATE_CHANGE
android.intent.action.ACTION_POWER_CONNECTED
android.intent.action.USER_PRESENT
Now, before Android O, everything was working fine. But since new limitations on background work, I'm having trouble with those broadcasts.
I constantly need to receive broadcast on events like change in WIFI state, or if the is device still or is in motion, even when the app isn't running.
I tried using JobScheduler to listen to wifi broadcasts, but it seems that the system still kills the service after certain time, moreover it stop working when I swipe the app out from recent-apps.
I was thinking, is using foreground service, to register the broadcast, is a good idea to solve this problem?
What would you suggest to solve this problem?
According to Android documentation usage of Manifest's implicit broadcast receivers is deprecated in Android Oreo and above
https://developer.android.com/about/versions/oreo/android-8.0-migration.html#rbr
I am trying to make an app that shows some information when you connect your phone to a charger during a specific period of the day.
Before Android Oreo this was easy, just add an Broadcast receiver and add android.intent.action.ACTION_POWER_CONNECTED to the intentfilter in the manifest.
Now I am struggling to find a working solution to create the same functionality.
I thought about periodically checking the device charging state but this feels wrong and it won't trigger immediately on connecting the device to a charger.
Registering the broadcast receiver from my application did not work either, when the application is closed the broadcast isn't received anymore.
Is there a battery friendly way to trigger an action when an Android device is connected to a charger in Android Oreo?
There are broadcasts which are exempted from the background execution limitations and for which broadcast receivers can still be registered in the manifest.
You could use the ACTION_BOOT_COMPLETED broadcast to start a service which registers a receiver for your ACTION_POWER_CONNECTED broadcast at runtime. (The service must be a foreground service. Otherwise, it may be destroyed.)
A other solution would be to use JobScheduler to create a job which requires charging. Then you don't need the foreground service.
As we know From Android Oreo google has restricted background services and broadcast. Many people are saying we can use jobScheduler in place of services. But i am unable to find any solution to handle implicit broadcast in background. Suppose i want handle WifiManager.NETWORK_STATE_CHANGED_ACTION in my app. i can register this action dynamically when app is foreground. but is that any way to listen same broadcast when app is in background. or any suggestion to achieve this.Thanks!!
Pasting the line from android official documentation
Apps that target Android 8.0 or higher can no longer register
broadcast receivers for implicit broadcasts in their manifest.
Apps can use Context.registerReceiver() at runtime to register a
receiver for any broadcast, whether implicit or explicit.
Which states that, you can still receive implicit broadcast at runtime, if you are managing your app to be run in background.
Additionally,
Here is the link about some tricks to make your app, run in a background:
Migrate an app to Android Oreo
Before Android 8.0, Oreo, you could detect a headset plugged in with a background service with a registered broadcast. With Android O's background execution limits, you can no longer do this without a notification.
While ACTION_HEADSET_PLUG is an excepted broadcast, it still doesn't send to Manifest registered receivers.
So you cannot use a background service. And you cannot be woken up via a manifest receiver. What's the solution? Never update your targetSDKVersion?
Seems, by official documentation, you can use ACTION_HEADSET_PLUG with no Android O limitation, because it is in the list of the exempted broadcasts:
Note: A number of implicit broadcasts are currently exempted from this
limitation. Apps can continue to register receivers for these
broadcasts in their manifests, no matter what API level the apps are
targeting. For a list of the exempted broadcasts, see Implicit
Broadcast Exceptions.
UPDATE:
But IRL, as CommonsWare wrote, there are only
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
flag for ACTION_HEADSET_PLUG and not Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND flag as, for example, for ACTION_LOCALE_CHANGED.
I want to know the difference between services and broadcast receivers, can anyone point out an example that can be observed on android mobile devices.
Thanks
Service: If you want to do something in background , this will be running always in background even if the application closed. You can create this in separate process and also you can give your service to other app if you want. Downloading any content or Music is good example
Broadcast Reciever: Usually system will send some info which can be recieved by your app if you would wish to ,by registering. And you can do something what you want when that thing happens by using onReceive method.
Example is the system will send BroadcastReceiver when new sms arrives or Booting done
Here is good article : Service and BroadcastReceiver
Service is used when you want to do something in background, any long running process can be done using Service in Background. For example, you want to play music when your application gets close. In that case service will be running in background with music.
Example of Service
BroadcastReceiver is used when you want to fire some stuff or code during some event. For example, event can be on Boot of Device. If you want to perform something when device Boots, date and time changed etc...
Example of BroadcastReceiver
I think of it possibly a different way. A Service receives intents that were sent specifically to your application, just like an Activity. A Broadcast Receiver receives intents that were broadcast system-wide to all apps installed on the device.
(The reason I say a Service is a bit like an Activity is that: You wouldn't broadcast a message saying "start Activity MyActivity" across all apps installed on the device. It is only for your specific app.)
Of course, as others mentioned, a Service can continue running in the background, whereas a Broadcast Receiver should finish quickly (e.g. if it is running for more than 5 seconds it may be killed by the OS). The Broadcast Receiver can still run in the background (when app is closed) under certain circumstances. For this, it's worth mentioning that there are actually two types of Broadcast Receivers - Manifest-declared, and Context-registered. They have different lifespans and restrictions - the former can receive broadcasts in the background with certain restrictions, while the latter cannot receive broadcasts in the background (app must be running and active) but has no restrictions on the types of intents that can be received.
Both services and broadcast receivers must be specifically invoked (via an intent), but for services this is usually a specific call (e.g. when your app is started or when the user clicks some button) whereas for broadcast receivers they don't need to be explicitly started as they will start anyway when a relevant broadcast is made.
Here's how I would think of it:
Type
Displays UI?
Can continue running for a long time when app is closed?
Can receive intents when app is closed?
Intents must specifically target your app?
Restricted list of intents that can be specified?
Activity
Yes
No
Yes
Yes
No
Service
No
Yes
Yes
Yes
No
Manifest-declared Broadcast Receiver
No
No
Yes
No
Yes1
Context-registered Broadcast Receiver
No
No
No
No
No
1: Only if you target Android 8.0 or above. The restrictions are not applied if the intent specifically targets your app. The restricted list of intents can be found here.