Boot completed Broadcast receiver is not working for dynamic registration - android

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.

Related

Android - Is it possible to declare Local Broadcast receiver in the manifest file?

I have declared my receiver in my manifest:
<receiver
android:name=".MyTestReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.ACTION_TEST"/>
</intent-filter>
</receiver>
And here is my MyTestReceiver class:
public class MyTestReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("com.example.ACTION_TEST".equals(action)) {
Toast.makeText(context, "Test!", Toast.LENGTH_SHORT).show();
}
}
}
But when I execute this code from elsewhere within my app:
Intent intent = new Intent("com.example.ACTION_TEST");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
...the local broadcast is not received (i.e., the toast is not shown).
Questions:
Is it possible to register a local broadcast receiver in the manifest?
If so, have I declared my local broadcast receiver incorrectly?
If it's not possible to declare a local broadcast receiver in the manifest, and I declare it in my Application subclass instead, will it have the same 'scope' as a receiver declared in the manifest? (I mean, will it receive broadcasts in all the same conditions/situations as it would if it was declared in the manifest?)
If there is a difference between specifying the receiver in the manifest than in my Application subclass, would I need to use general (non-local) broadcasts rather than local broadcasts? (In the actual app, the local broadcast will be sent when my IntentService completes its work. The IntentService will be triggered by an FCM push message.)
NB - All I can seem to find about this in the documentation is:
Note: To register for local broadcasts, call
LocalBroadcastManager.registerReceiver(BroadcastReceiver,
IntentFilter) instead.
...which doesn't address the main issue of whether or not you can specify the receiver in the manifest.
Is it possible to register a local broadcast receiver in the manifest?
No.
and I declare it in my Application subclass instead, will it have the same 'scope' as a receiver declared in the manifest? (I mean, will it receive broadcasts in all the same conditions/situations as it would if it was declared in the manifest?)
Well, no. A manifest-registered receiver is for system broadcasts, originating from any process. LocalBroadcastManager is local, for "broadcasts" within your own process.
You are welcome to register a receiver with LocalBroadcastManager in your Application (e.g., in its onCreate()), but I suspect that there are better solutions for whatever problem you are trying to solve.
In the actual app, the local broadcast will be sent when my IntentService completes its work
Then the receiver should be registered in the activity or fragment that needs to know about that work being completed. Your Application is unlikely to need to know about that work being completed, as if it did, your IntentService could just call a method on the Application and bypass all this broadcast stuff.

Doubts about Intents and BroadcastReceiver

Im quite new on Android programming, so I have some basic doubts.
There is an App here that do not have the BroadcastReceiver, but I used other class instead, and I am sure that it works properly.
I read in some topics, that i need to register It in manifest, but I have no clue how to do It; and I got confused about com.google.android.c2dm.permission.SEND and etc, I do not know how to set it.
Question: Can I ask for someone explain to me, in simple way, what I need to do to my method be executed while the app is closed, AND, how i register it on manifest?
Thanks!
Send an Intent is the way of Android of telling to everyone that some event occured.
For instance where your device receive a call an Intent is broadcast. But to be specific to some event every Intent has an action. For instance the Intent broascast when you receive a SMS has the "android.provider.Telephony.SMS_RECEIVED" action.
In your AndroidManifest.xml you can register objects for specific intents. You can register Activity, Service and BroadcastReceiver.
To register a BroadcastReceiver to "receive sms action" you do the following in your manifest :
<receiver android:name="your.receiver.class">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
This means that every time an Intent with the specified action is fired, it will be pass to your receiver. This means that his onReceive method will be called with the intent as param.
So to create some code that will be executed will your app is closed, follow this steps :
Create a class that extends BroadcastReceiver.
Put your code in the onReceive method. This method will be call every time your receiver receive an intent.
Register your receiver for the desired action in your AndroidManifest.xml file.
BroadcastTeceiver as the name imply is component that could receive data that someone send via Intents. The sender could be the system, other App or your App itself.
There are to ways to regiester BroadcastReceiver:
In the manifest by exlixit the Intent you want to listen.
In code by give it Intent_filter programmatically.

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

Broadcast Receiver Register in Manifest vs. Activity

I need some help to understand when I can expect my broadcast receiver will work when just registered in the manifest versus having to be registered from a running activity or service.
So for example if I register a stand alone receiver with the following intent filter it works without having a service/activity reference to it:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blk_burn.standalonereceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name="TestReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY"/>
</intent-filter>
</receiver>
</application>
</manifest>
However if I replace android.media.AUDIO_BECOMING_NOISY with android.intent.action.HEADSET_PLUG the receiver is not triggered (Android Documentation)
From what I found on this site you have to register this receiver from an activity or service that is already running for it to work (Post).
Can anyone tell me why this does not work when just adjusting your intent filter in the manifest and why you need to have a service running in the background that references/registers the receiver?
Is there a work around so that I can just register my receiver in my app's manifest using an intent filter with android.intent.action.HEADSET_PLUG?
How can do I identify which Broadcast actions from the android documentation need to have a service or activity register them versus just having the right filter in the manifest?
If your receiver is registered in the manifest, and your app is not running, a new process will be created to handle the broadcast. If you register it in code, it's tied to the life of the activity/service you registered it in. For some broadcasts, it doesn't really make sense to create a new app process if it doesn't exist, or there are some security, performance, etc. implications, and thus you can only register the receiver in code.
As for the HEADSET_PLUG broadcast, it seems the idea is that your already running app can get this to do app-specific adjustments to UI, volume, etc. If your app is not running, you shouldn't really care about the headphones being unplugged.
AFAIK, there is no single place this info is summarized for all broadcasts, but each Intent should have a comment in the JavaDoc about how to register and use it, but apparently it's lacking in places. You should be able to compile a list if you grep the Android source tree for Intent.FLAG_RECEIVER_REGISTERED_ONLY.
As usual broadcast receivers can be configured in the manifest fileAndroidManifest.xml. A BroadcastReceiver that is configured in this way is called statically registered.
You can register your receiver in the manifest file by using the element:
<receiver
android:name=".ConnectivityChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
The nested element is used to specify the event the receiver should react to.
Dyanmic Broadcast Recievers
As an alternative you can register your BroadcastReceiver implementation dynamically in your code. You just need to call the registerReceiver() method on your Context object.
The registerReceiver() method takes two parameters:
The arguments of the registerReceiver() method
receiver : The BroadcastReceiver you want to register
filter : The IntentFilter object that specifies which event your receiver should listen to.
When you register your receiver in this way, it lives for as long as the component livesand Android sends events to this receiver until the creating component itself gets destroyed.
It’s your task to handle the lifecycle correctly. Thus when you add a receiver dynamically, take care to unregister the same receiver in the onPause() method of your Activity!
I suggest to register the receiver in the onResume() method of your Activity and to unregister it in your onPause() method:
#Override
protected void onPause() {
unregisterReceiver(mReceiver);
super.onPause();
}
#Override
protected void onResume() {
this.mReceiver = new ConnectivityChangeReceiver();
registerReceiver(
this.mReceiver,
new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
super.onResume();
}
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