About sticky intent ACTION_BATTERY_CHANGED - android

I'm using this code:
Intent i = getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
and as far as I understand i should be null if ACTION_BATTERY_CHANGED didn't occur, but it is never null and always returns me the same data.
It worked fine when I used a broadcast receiver. Do I need to delete the Intent after receiving it?

As soon as you register sticky intents will always deliver you last broadcasted data. So that is the reason you are always recieving data

Sticky=property of adhering
result=which intent adhered with os called sticky intent
Normally you send broadcast a receiver using sendBroadcast(Intent) But When you are calling this method sendStickyBroadcast(Intent) it means that A broadcast Intent can be specified to be sticky in which case it will be retained by the system after it has been sent. But by default Intent.ACTION_BATTERY_CHANGED intent is sticky.
read the full post here http://iphoidtech.com/uncategorized/what-is-stcky-intent/

Related

Which Intents/Broadcasts could be "sticky" in Android?

Where can I find information which Intent/Broadcast can be sticky?
Example of a sticky broadcast sent via the operating system is ACTION_BATTERY_CHANGED. When I call registerReceiver() for that action with a null BroadcastReceiver — I get the Intent that was last Broadcast for that action.
Whenever I find the last value by:
//In Activity
val batteryIntent = registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)); //sticky
val level = batteryIntent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
val scale = batteryIntent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
This Intent: AudioManager.ACTION_HEADSET_PLUG works too, but some Intents don't work: LocationManager.MODE_CHANGED_ACTION, Intent.ACTION_POWER_CONNECTED BluetoothDevice.ACTION_ACL_CONNECTED, ... I know, some don't make sense, but result of these Intents are always null, even if there has been a change, why?
For ACTION_BATTERY_CHANGED there is information: "This is a sticky broadcast ..." in doc, but for ACTION_HEADSET_PLUG no.
Is exist any restriction or split to sticky / non-sticky or list which Intents work as sticky?
Why do some Intents work and others don't?
Thank you.
Where can I find information which Intent/Broadcast can be sticky?
Look at the source code for the Android version of interest, searching for sendStickyBroadcast().
Is exist any restriction or split to sticky / non-sticky or list which Intents work as sticky?
Sticky broadcasts are sent using sendStickyBroadcast(). Technically, it is not tied to a specific Intent.

Knowing about Sticky intent in Android

In android there are 3 kinds of Intents,
Intent,
Sticky Intent,
Pending intent.
so What is sticky intent?
Intent - is a message passing mechanism between components of Android, except for Content Provider. You can use Intent to start any
component.
Sticky Intent - Sticks with Android, for future broadcast listeners. For example if BATTERY_LOW event occurs then that Intent
will stick with Android so that any future requests for
BATTERY_LOW, will return the Intent.
Pending Intent - If you want some one to perform any Intent operation at future point of time on behalf of you, then we will use
Pending Intent.
An intent that is used with sticky broadcast, is called as sticky intent.
This intent will stick with android system for future broadcast receiver requests.
OR
sendStickyBroadcast() performs a sendBroadcast(Intent) known as sticky, i.e. the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value of registerReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent). One example of a sticky broadcast sent via the operating system is ACTION_BATTERY_CHANGED. When you call registerReceiver() for that action -- even with a null BroadcastReceiver -- you get the Intent that was last broadcast for that action. Hence, you can use this to find the state of the battery without necessarily registering for all future state changes in the battery.
Pending Intent: Pending Intent is actually an object which wraps an Intent to do some future work by another app.
It lets us pass a future Intent to another application and allows that application to execute that Intent as if it had the same permissions as our application, whether or not our application is still around when the Intent is eventually invoked.
A PendingIntent is generally used in cases were an AlarmManager needs to be executed or for Notifications. A PendingIntent provides a mean for applications to work, even after their process exits.
PendingIntent uses the following methods to handle the different types of intents:
PendingIntent.getActivity() : Retrieve a PendingIntent to start an Activity
PendingIntent.getBroadcast() : Retrieve a PendingIntent to perform a Broadcast
PendingIntent.getService() : Retrieve a PendingIntent to start a Service
Example :
Intent intent = new Intent(this, SomeActivity.class);
// Creating a pending intent and wrapping our intent
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
try {
// Perform the operation associated with our pendingIntent
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
Intent: Intent is basically a message passing mechanism between different components of Android, except for Content Provider. You can use intent to start any component in Android.
Sticky Intent: These are the Intents which sticks with Android for future broadcast listener.
Sticky Intent is also a type of Intent which allows communication between a function and a service sendStickyBroadcast(), performs a sendBroadcast(Intent) known as sticky, the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value of registerReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent).
One example of a sticky broadcast sent via the operating system is ACTION_BATTERY_CHANGED. When you call registerReceiver() for that action — even with a null BroadcastReceiver — you get the Intent that was last Broadcast for that action. Hence, you can use this to find the state of the battery without necessarily registering for all future state changes in the battery.
Intent : Intent is an asynchronous message which is use to communicate between the components in android , except Content Provider.
for example you can start activity by
startActivity(Intent intent);
Sticky Intent : sticky intents are associated with the android system for the future broadcast events.
Pending Intent : Those intent which you want to trigger at some time in future when you application is not alive.
An intent that is used with sticky broadcast, is called as sticky intent. This intent will stick with android system for future broadcast receiver requests.
Sticky Intent allows a communication between function and a service sendStickyBroadcast() performs a sendBroadcast(Intent) know as sticky, the Intent you are sending stays around after the broadcast is complete so that others can quickly retrieve that data through the return value of registerReceiver(BroadcastReceiver, IntentFilter). In all other ways, this works the same as sendBroadcast(Intent).

Why receiver receive broadcast every time the onResume() method activated?

In my onresume() of activity, I have this
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mReceiver, intentFilter);
Every time the onResume() activate, mReceiver always received a broadcast have the action of ConnectivityManager.CONNECTIVITY_ACTION
That's strange, because my networkstate is in a stable wifi and does not changed at all.
every time onresume is activited , registerReceiver is called one more each time.
registerReceiver sends bck sticky broadcasts. Sticky broadcasts are sent to receiver as soon as registerBroadcast is called.
you can use unregisterReceiver or check you will have to check whether you have already registered and skip , if yes..
As per documentation for registerReceiver (BroadcastReceiver receiver, IntentFilter filter):
The system may broadcast Intents that are "sticky" -- these stay around after the broadcast as finished, to be sent to any later registrations. If your IntentFilter matches one of these sticky Intents, that Intent will be returned by this function and sent to your receiver as if it had just been broadcast.
Though you are just registering your receiver right now but it's up to the system when to broadcast that Intent and since that intent is a sticky one so it gets broadcasted as soon as you register.
Check out this ConnectivityManager.CONNECTIVITY_ACTION, always broadcast when registering a receiver?
Seems sticky broadcasts is a common problem for action ConnectivityManager.CONNECTIVITY_ACTION,
Follow the instruction I tried to describe the receiver in XML but it seems NOT OK with that
AT last,I used a flexible method to resolve this:Since everytime in Onresume will send that broadcast,I set a boolean value to be 'false',when the onresume called the receiver for the first time,the program will do nothing but just set this boolean value to 'true'.
Then when CONNECTIVITY changed,it will go normal process.
This seems not an elegant method ,but it worked in my app.
A solution is to use isInitialStickyBroadcast in the onReceive callback of your BroadcastReceiver to know if you are actually proceeding a sticky broadcast and act accordingly (BroadcastReceiver : isInitialStickyBroadcast)

Android: How can I completely abort/remove sticky broadcast

We can remove an ordered broadcast with abortBroadcast(), is there a way to completely remove a sticky ordered broadcast?
removeStickyBroadcast is exactly what you need:
public abstract void removeStickyBroadcast (Intent intent)
Since: API Level 1
Remove the data previously sent with sendStickyBroadcast(Intent), so that it is as if the sticky broadcast had never happened.
You must hold the BROADCAST_STICKY permission in order to use this API. If you do not hold that permission, SecurityException will be thrown.
Parameters
intent The Intent that was previously broadcast.
http://developer.android.com/reference/android/content/Context.html#removeStickyBroadcast(android.content.Intent)

In my broadcast receiver 's onreceive() method, how can I tell the origin of the Intent

In the broadcast receiver's onReceive() method, how can I tell which app send me the Intent?
This is not the intent of how android uses Intents (no pun intended.). However, if you are sending the intent and your broadcaster is receiving the intent, you can use setExtra ( String, String) on the Intent to attach the name of the class sending the intent. Inside your onReceive, check to see if that extra is set and, if it is, check to see if the value matches your expected class.

Categories

Resources