Can broadcastreceiver take full control? - android

I have the following question:
Is it possible to completely override a phone-function when receiving a BroadcastReceiver? For example, is it possible to receive sms and do not let the sms to appear in the notification area?
thanks

Yes it is possible just define your BR like below code. make sure you call abortBroadcast(); method from receiver so it wont allow to further call onReceives of other BRs.
<receiver android:name=".SMSReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Permission
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
but it wont guaranteed to work all the time as there may be other apps doing same and could have abortedBroadcast, so there may be chances even your onReceive wont be tringger.

Sometimes. It depends on what type of broadcast it is. Take a look through the docs for BroadcastReceiver:
There are two major classes of broadcasts that can be received:
Normal broadcasts (sent with Context.sendBroadcast) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here.
Ordered broadcasts (sent with Context.sendOrderedBroadcast) are delivered to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled with the android:priority attribute of the matching intent-filter; receivers with the same priority will be run in an arbitrary order.
SMS happens to be an ordered broadcast, so in this case if you call abortBroadcast, other receivers with a lower priority will not be called. This will only work if your priority is the highest though, which is not really possible to guarantee, but you can do a reasonable job by just setting a very high priority, perhaps over 9000 might be appropriate. Although the docs do say to not use anything 1000 or over, this is to ensure that the system always gets to handle the broadcasts. In your case though, you really do want to stop the system from handling the broadcast.

Related

which broadcast receiver does execute first: dynamic or static?

While working with Android, I have one broadcast receiver which registers dynamically as well as statically. So my question is which has max priority to execute.
It depends on the priority set for particular BroadcastReceiver:
If the priority is not set, the receivers will be executed in an arbitrary order.
If the priority is set to the receiver either by using
<intent-filter android:priority="999"> in AndroidManifest.xml
OR
filter.setPriority(999); when registered through code.
Receiver with higher priority will be executed first.

Android: what's the meaning of exported receiver's attribute?

<receiver
android:name="MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I don't understand if it's needed to be notified.
If it were true any app could call my receiver with those actions? So If I make it false the system can send the actions to my receiver?
I don't understand if it's needed to be notified. If it were true any
app could call my receiver with those actions? So If I make it false
the system can send the actions to my receiver?
Actually, others apps cannot "call your receiver". Other apps can just send broadcast Intents. The System will then call all registered receivers.
In general you shouldn't worry about this. Most of these broadcast Intents are protected so that only system apps can broadcast them anyway. An attempt by another app to broadcast BOOT_COMPLETED, for example, would just be ignored. What would happen if your BroadcastReceiver gets triggered by a rogue app because it broadcast CONNECTIVITY_CHANGE? Probably nothing, because your app should check the real connectivity state in onReceive() anyway, and if there isn't any change you can just ignore it.
Also, you don't need to specify android:enabled="true" because this is the default state. You also don't need to specify android:exported="true" because you have an <intent-filter> attached to your <receiver> which automatically sets android:exported to true.
If you set android:exported ="false", implies that the receiver is intended only for application-internal use.
Note: This attribute is not the only way to limit a broadcast receiver's external exposure. You can also use a permission to limit
the external entities that can send it messages
Adding to #SaravInfern's answer. Here is the relevant permission doc for limiting external entities that can send the receiver messages:
https://developer.android.com/training/permissions/restrict-interactions#broadcast-receivers

Android shutdown/power off broadcast receiver not starting

I want to create a traffic widget, and store the used traffic at each device shutdown. The problem is that I can't get the shutdown receiver to trigger.
I used the following code:
IntentFilter actionShutdown = new IntentFilter("android.intent.action.ACTION_SHUTDOWN");
IntentFilter quickPOFF = new IntentFilter("android.intent.action.QUICKBOOT_POWEROFF");
TrafficDataUpdate trafficDataUpdate = new TrafficDataUpdate();
getContext().registerReceiver(trafficDataUpdate, actionShutdown);
getContext().registerReceiver(trafficDataUpdate, quickPOFF);
I also tried with the receiver declared in manifest, but no success:
<receiver android:name=".receivers.TrafficDataUpdate">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN"/>
<action android:name="android.intent.action.QUICKBOOT_POWEROFF"/>
</intent-filter>
</receiver>
Do you have suggestions?
Can someone recommend me another way of counting the data traffic, without the shutdown receiver?
Use one IntentFilter, not two, teaching it to listen for both actions. Your second registerReceiver() is implicitly unregistering the first receiver.
Also note that this will only work so long as your process is still in memory. Usually, your process is not in memory, and it is in the user's best interests for your process to not be in memory. Please replace this implementation with one where the receiver is registered in the manifest, as is shown in the following StackOverflow threads:
Android ACTION_SHUTDOWN Broadcast not working
BroadcastReceiver's behaviour for ACTION_SHUTDOWN
handling phone shutdown event in android

Boot completed Broadcast receiver is not working for dynamic registration

I created a broadcast receiver and registered in in manifest using following approach it is working fine
static way registering broadcast receiver (working fine)
<receiver
android:name="DeviceRestartListener"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</category> -->
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
But when i tried to register the broadcast receiver programmatic (instead of static way) using following way it doesnt work
Programmetic registering (not working)
DeviceRestartListener dataBroadcastReceiver = new DeviceRestartListener();
IntentFilter filter = new IntentFilter();
filter.addAction(
"android.intent.action.BOOT_COMPLETED")
//registerReceiver(dataBroadcastReceiver, filter); //DOESNT WORK
registerReceiver(dataBroadcastReceiver, filter, "android.permission.RECEIVE_BOOT_COMPLETED", null); //DOESNT WORK
No compilation and run time error. But the receiver is not receiving broadcast after device restarts
Thanks
All the Broadcast receivers will not work even when they are statically declared in manifest or registered dynamically using Application context. for example Intent actions like
Intent.ACTION_SCREEN_OFF
and
Intent.ACTION_SCREEN_ON
have to be registered dynamically. These actions will not be fired when they are declared in manifest. some Intent actions like
Intent.ACTION_TIME_CHANGED;
Intent.ACTION_TIME_TICK;
Intent.ACTION_TIMEZONE_CHANGED;
will be fired when are registered dynamically through context whose window token is not null.(like Activity or Dialog).
similar to this, some of the Intent actions like
Intent.ACTION_BOOT_COMPLETED
will work only when they are registered statically using manifest
Register receiver in code
When we register a receiver in code, we must unregister it when the app gets destroy (actually, when the Activity or Service that register it, gets destroy).
Register receiver in manifest
When we declare it in the manifest, you make it available even if you app is not running.
When to use which method to register
Which method to use for registering your BroadcastReceiver depends on what your app does with the system event. I think there are basically two reasons why your app wants to know about system-wide events:
Your app offers some kind of service around these events
Your app wants to react graciously to state changes
Examples for the first category are apps that need to work as soon as the device is booted or that must start some kind of work whenever an app is installed. Battery Widget Pro or App2SD are good examples for these kinds of apps. For this type you must register the BroadcastReceiver in the Manifest file.
Examples for the second category are events that signal a change to circumstances your app might rely on. Say your app depends on an established Bluetooth connection. You have to react to a state change – but only when your app is active. In this case there is no need for a statically registered broadcast receiver. A dynamically registered one would be more reasonable.
There are also a few events that you are not even allowed to statically register for. An example for this is the Intent.ACTION_TIME_TICK event which is broadcast every minute. Which is a wise decision because a static receiver would unnecessarily drain the battery.

Battery broadcast receiver declared in manifest file does not work?

There are two ways to make a broadcast receiver known to the system: One declares it in the manifest file with this element. The other is to create the receiver dynamically in java code.
Now, the receiver has been created dynamically in java code and it does work normally.But why the first way "Declare in the manifest file" failed?
Is there anyone to success?
Thanks.
AndroidManifest.xml
<receiver android:name="pj.batteryinfo.BatteryReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"></action>
</intent-filter>
</receiver>
For some actions, you could only declare the BroadcastReceiver in Java code. This happens to the BATTERY_CHANGED action and SCREEN_ON,SCREEN_OFF so far as I know.
When you declare a BroadcastReceiver in the Manifest.xml file, no matter whether your app is running or not, the BroadcastReceiver will be awaken and thus the onReceive method will be called.
Why?I think this is because the BATTERY_CHANGED action is very common to take place and if you can declare it in the Manifest, the system will often send a lot of broadcasts and thus consumes battery dramatically;however, when you declare it in the code, the broadcastReceiver will only be effective when the activity is running and thus avoid extreme battery consumption. To save battery, Android doesn't allow such actions to be registered in the file.
This is just my guess. I didn't see any official explanations on this. As a developer, I just memorize such actions, rather than the reasons behind them.

Categories

Resources