I am working on broadcast receiver and stuck in a problem.
I am receiving a broadcast receiver in Manifest file.
<receiver class=".MyClass" android:name=".MyClass">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
this is working fine and it is calling MyClass whenever there is change in connectivity.
Now the problem is whenever my application is not running still this class will receive broadcast receiver. I want it to receive whenever the application is running.
I tried it by extending BroadcastReceiver registering and unregistering broadcast in that class file and it works. But i want to achieve the same by Manifest file.
My problem will solve if it is not receiving anything when application is not opened.
What you are talking is not possible. The whole purpose of having the intent filter in the manifest is being able to receive the intent whether or not your application is running. The only way to do what you want to is by registering/unregistering the receiver from the code [registerReceiver]
The question was asked a long time ago but in case some one landed on this page while searching, It is possible to register and unregister broadcast receiver from code instead of doing that from manifest file. (Checking the Networking Connectivity using BroadcastReceiver in Android)
You said "My problem will solve if it is not receiving anything when application is not opened".
Here how I understand your question and appropriate answer.
android:enabled
Whether or not the broadcast receiver can be instantiated by the system — "true" if it can be, and "false" if not. The default value is "true".
If you want to enable your receiver at runtime, you can set the state to disabled initially. You can do so in the manifest file:
<receiver
android:name=".YourReceiver"
android:enabled="false" >
<!-- your intent filter -->
</receiver>
Source:
http://developer.android.com/guide/topics/manifest/receiver-element.html#enabled
http://www.grokkingandroid.com/enabling-and-disabling-broadcastreceivers/
Related
<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
I have an app for which I've added some functionality for when a call is coming in (phone ringing or answered). I did so by creating a BroadcastReceiver like this:
<receiver android:name="mypackage.PhoneReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" >
</action>
</intent-filter>
</receiver>
It is all working well but the problem is that it gets called even when my app isn't running, which makes sense but this triggers all sorts of other things on my app.
So the question is, can I have that BroadcastReceiver triggered only if my app (or a service I have) is running? or have my Application.onCreate() somehow know it is being created for the BroadcastReceiver and skip everything else it usually does?
Thanks.
You can take the receiver Off of the manifest, and register it programmatically in your code. Doing so, you can register/unregister whenever you want.
While it is possible to declare a 'Local' BroadcastReceiver via code so it receives intents published via a LocalBroadcastManager.Ex
LocalBroadcastManager.getInstance(this).registerReceiver(new FooReceiver(), new IntentFilter("foo_intent_filter"));
I wonder if it is possible to declare such receiver via the manifest.xml (cleaner) .
When I use the 'manifest way', the receiver is not 'receiving' the intents.
<receiver
android:name="FooReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="foo_intent_filter" />
</intent-filter>
</receiver>
Am I missing something? or the code-way is the only viable solution.
Thanks
I wonder if it is possible to declare such receiver via the manifest.xml (cleaner) .
First, that is not possible.
Second, registering in the manifest has little to do with it being "cleaner". It is to allow Android to instantiate the receiver on its own, so that you can respond to broadcasts when your process is not running. And, in the specific example that you cite, it is to allow any app on the system to send you a broadcast. Neither of those are relevant for LocalBroadcastManager.
I know that setting android:exported="false" will restrict other applications from using/accessing my application components.
Does setting this attribute will restrict the system as well from using/accessing my components? i doubt.
for example, i have the following receiver:
<receiver
android:name="ConnectivityManager"
android:label="NetworkConnection"
android:exported = "false" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
The receiver is still receiving broadcasts from the system once the connection state changes (on/of).
Does this mean that the system calls/access can never be stopped? Please illustrate.
Google‘s online document does not describe this clearly.
From the real result, the receiver can still be triggered by system broadcast even if set exported="false".
Yes, if exported="false", it will still respond to system broadcasts such as connectivity changes. This is easy to test by using your above broadcast-receiver and toggling airplane mode
I have an broadcast receiver registered in the manifest for intercepting calls, like this:
<receiver android:name="CallTracker">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
Everything works fine and the receiver gets called.
But after I restart the device or my AVD, the receiver doesn't get called anymore.
What do I have to do in order to get my broadcast receiver to work after reboot, too?
Do I need PackageManager for that?
I like the registration in the manifest, since the application doesn't have to be active in order for the app to intercept the call.
I know that this question is quite old but in my opinion still relevant. Since the currently accepted answer is wrong and the comment by user1806772 was the correct answer for me, I provide it as a new answer to the question:
It probably does work. But directly after reboot it can take a really long time (up to multiple minutes) until the intent is delivered. Some minutes after the reboot it should work fast again.
You need to add this action to your intent-filter.
<action android:name="android.intent.action.BOOT_COMPLETED" />