I see that some broadcast receiver use this tag android:exported="true" in Android Manifest.xml to register.
<receiver android:exported="true" android:name="com.flyingsoftgames.googleplayquery.QueryReceiver">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
What exactly the use of android:exported="true" to register broadcast receiver in Android?
From the Developer Guide:
android:exported
Whether or not the broadcast receiver can receive messages from sources outside its application — "true" if it can, and "false" if not. If "false", the only messages the broadcast receiver can receive are those sent by components of the same application or applications with the same user ID.
The default value depends on whether the broadcast receiver contains intent filters. The absence of any filters means that it can be invoked only by Intent objects that specify its exact class name. This implies that the receiver is intended only for application-internal use (since others would not normally know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the broadcast receiver is intended to receive intents broadcast by the system or other applications, so the default value is "true".
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 (see the permission attribute).
android:exported
true : broadcast receiver can receive events sent by same or others applications
false : broadcast receiver can receive events sent by same application
Related
On my Android App, when LOCALE is changed I'm trying to invoke a JobIntentService to prevent ANR, but before even my BroadcastReceiver is invoked, it gets timed out(no ANR).
Error
E ActivityManager: Reason: Broadcast of Intent {
act=android.intent.action.LOCALE_CHANGED flg=0x11200010
cmp=com.company.locale.LocaleChangeReceiver } has timed out via system
broadcast.
AndroidManifest.xml
<!-- Listen to locale change -->
<receiver android:name="com.company.locale.LocaleChangeReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED"/>
</intent-filter>
</receiver>
You should not set android:exported to false. This will limit broadcast receiver's external exposure. If it is set to false 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
I am trying to send a broadcast message from one app to another.
val intent = Intent()
intent.setClassName("com.company.receivingapp","com.company.receivingapp.receivers.WakeReceiver")
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
requireContext().sendBroadcast(intent)
Meanwhile the receiving app has declared
<receiver
android:name=".receivers.WakeReceiver"
android:enabled="true"
android:exported="true">
</receiver>
The following happens when I run this:
NOTHING.
No error messages.
No exceptions.
Nothing interesting in logcat.
I know that implicit broadcasts in manifests are becoming illegal. But what about explicit broadcasts in manifests?
All the examples I see are.
Implicit broadcasts using manifest
Explicit broadcasts using dynamically registered type
Is that because Explicit Broadcasts of statically registered receivers don't work?
Does that Intent.FLAG_INCLUDE_STOPPED_PACKAGES actually do anything?
<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
In view of the security model in Android, I'm trying to use custom permissions with a broadcast receiver.
WHAT I'VE DONE :
I have declared a custom permission for the receiver, thereby limiting the broadcasts that it can receive. Some code from manifest:
<permission android:name="abc"/>
<receiver android:name=".UpdateUserReceiver"
android:permission="abc"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.ACTION_UPDATE_USERNAME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Now I expect that receiver UpdateUserReceiver will only receive broadcasts from components which use the permission 'abc'.
Broadcast sending code:
// Update username. Invoke broadcast.
Intent updateUserBroadcast = new Intent();
updateUserBroadcast.putExtra("username", userName);
updateUserBroadcast.setAction("android.intent.action.ACTION_UPDATE_USERNAME");
sendBroadcast(updateUserBroadcast);
Activity which sends broadcast :
<activity android:name=".UpdateUserNameActivity">
<intent-filter>
<action android:name="com.intent.action.UPDATE_USERNAME"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Question 1 :
As seen, the activity nowhere uses the permission which the receiver has declared, so that it can receive the broadcast from the activity. But still the receiver is invoked, and I suspect it's due to the use of implicit intents though I'm not sure. Any ideas?
Question 2 :
What's the difference between the permission tag declared at app level, and android:permission tag inside the receiver? I understand the use of 2nd one, which enforces a permission before anyone can expect the receiver to receive the broadcast, but then why's the first one required. Is it needed for this scenario, or can it be removed. Either way, I have checked that the receiver receives the broadcast.
Answer 1:
the <uses-permission> tag in <manifest> requests a permission for all component in this application, you don't need to request a permission for a single activity. And The application declares the custom permission use <permission> will automaticall holds it, no necessary to request it again.
I guess your activity and the receiver are in the same application.
"implicit intents" can not break the "permission rule".
Answer 2:
the <permission> in <application> will set a permission that applies to all of the application's components.
check here:
http://developer.android.com/guide/topics/manifest/application-element.html#prmsn
But still the receiver is invoked, and I suspect it's due to the use of implicit intents though I'm not sure
No.
Any ideas?
They are both in the same app ("because here my activity and receiver are in the same application"). Permissions are applied between apps, as part of inter-process communication (IPC), not within an app.
What's the difference between the permission tag declared at app level, and android:permission tag inside the receiver?
<permission> defines the permission. android:permission applies the permission. To draw a Java analogy, <permission> defines a field, android:permission uses the field.
Ok got your point. you might be sending the broadcast from the same application. Have you tried sending the broadcast from different app? Look at this code. There is a PID check if calling PID is same app then permission will be granted by default. Hence your receiver is getting executed with out any problem.
http://androidxref.com/4.4.4_r1/xref/frameworks/base/core/java/android/app/ActivityManager.java#2109
Can anybody tell me when should I use intent filter and broadcast receiver?
<activity>
<intent-filter></intent-filter>
</activity>
and
<receiver>
<intent-filter></intent-filter>
</receiver>
I think you are confused about implicit intent and broadcast receiver. Intent Filter in Activity is for receiving implicit intent, while that in Receiver is for receiving broadcast. The OS deliver an broadcast msg to all Receivers, while it deliver an implicit intent to a certain one activity. See here
From the documentation:
A broadcast receiver is a component that responds to system-wide
broadcast announcements. Many broadcasts originate from the system—for
example, a broadcast announcing that the screen has turned off, the
battery is low, or a picture was captured. Applications can also
initiate broadcasts—for example, to let other applications know that
some data has been downloaded to the device and is available for them
to use. Although broadcast receivers don't display a user interface,
they may create a status bar notification to alert the user when a
broadcast event occurs. More commonly, though, a broadcast receiver is
just a "gateway" to other components and is intended to do a very
minimal amount of work. For instance, it might initiate a service to
perform some work based on the event.
You can use broadcast receiver by two ways.
1) Registering and un-registering in your activity.When you register with your activity you need to pass an action for which it will take care and it will fire when we send broadcast with that action from our application.
2) Second way to use broadcast reciver to register in manifest file and mention action in intent filter for that in manifest file.
Intent filter is nothing but in simple words "It is filter just we use in our usual lives." It will filter the actions for calling it.
Intent filter is same for activity and broadcast receiver.Its main functioning is to filtering the action.It depends on us how to utilize it.One major example is in our each application in manifest file we specify
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
in our launcher activity.It suggests this activity is our launcher activity and will run first at start of our application.If you not specify it then your application will not launch.Also we can not specify these types of filter in broadcast receiver's intent filter.They are not launcher of apps,