So I have 2 apps - A and B.
In A i have a BroadcastReceiver. In the receiver tag (manifest file) I specify an android:permission string (let's say com.example.app.SEND). Now B cannot send broadcasts to A anymore. Makes sense!
So what do I have to do in order for B to send broadcasts to A ? In B's manifest, I specified uses-permission tag with android:name set to the same string (com.example.app.SEND) as the receiver's android:permission but still the broadcasts won't go from B to A.
What am I doing wrong ? Or is there something else that needs to be done ?
-- Update --
Here's my app A's receiver tag:
<receiver
android:name="com.example.app.MyReceiver"
android:enabled="true"
android:exported="true"
android:permission="com.example.BReceiver.SEND" >
<intent-filter>
<action android:name="com.example.BReceiver" />
</intent-filter>
</receiver>
And here's the uses-permission tag from my B's manifest:
<uses-permission android:name="com.pycitup.BReceiver.SEND" />
So I'd to set a custom permission for the same string like this in B's manifest:
<permission android:name="com.pycitup.BReceiver.SEND" />
Was quite straight-forward and simple. Just required a bit of reading across the web.
From B create an intent and set the action to your broadcast receivers name.
Intent myintentB=new Intent();
myintentB.setAction("com.example.app.SEND");
sendBroadcast(myintentB);
This should technically hit your receiver.
Related
I try to receive an event everytime a new shortcut on the Homescreen/Luncher was created. After my app receive the event I like to modify the shortcut. My current configuration is listed below, but I never receive an event.
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<application>
<receiver
android:name=".InstallShortcutReceiver"
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
<intent-filter>
<action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
</intent-filter>
</receiver>
</application>
Is my idea possible ?
Best Regards,
André
What happens if you remove the permission line from the receiver? The permission you specify in a receiver like that is the permission necessary to call it, not for it to receive broadcasts.
I found it. When I shortcut is created using drap and drop from the menu no INSTALL_SHORTCUT event is published.
I have some receivers declared in my AndroidManifest :
<!-- no warning -->
<receiver
android:name=".receivers.TriggerMonitoringBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- no warning -->
<receiver
android:name=".receivers.ScanResultsReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.net.wifi.SCAN_RESULTS" />
</intent-filter>
</receiver>
<!-- warning : Exported receiver does not require permission-->
<receiver
android:name=".receivers.BatteryMonitoringReceiver"
android:enabled="false">
<intent-filter>
<action android:name="#string/intent_action_setup_alarm" />
<action android:name="#string/intent_action_cancel_alarm" />
<action android:name="#string/intent_action_monitor" />
</intent-filter>
</receiver>
The first one is meant to receive a BOOT_COMPLETED action. The second is meant to receive android.net.wifi.SCAN_RESULTS. The third one is meant to receive some actions I broadcast (intent_action_monitor) and some actions broadcasted by the AlarmManager (intent_action_setup_alarm etc).
Two questions:
Why don't I get the warning on all receivers?
What permissions do I need to set for receivers meant to receive from system services to correct the warning (I understand what it is about and I don't want anyone to use my receivers anyway) ? Will exported="false" do for boot receivers, wifi receivers, alarm receivers etc?
I thought of using a custom permission with android:protectionLevel="signatureOrSystem" but the docs advise against both this protection level and custom permissions. So how I should handle this warning ?
Links to the docs and/or some code will be much appreciated.
Why don't I get the warning on all receivers ?
Because the first two are clearly designed to be broadcast by Android. The last one is unknown, partly because you did not supply the string resource values, and possibly because they are your own unique action strings.
What permissions do I need to set for receivers meant to receive from system services to correct the warning
The correct solution is to delete the <intent-filter>. If you are broadcasting these Intents, or if you are wrapping an Intent in a getBroadcast() PendingIntent, you do not need action strings. Use the Intent constructor that takes the Java class object as the second parameter, and use that:
new Intent(this, BatteryMonitoringReceiver.class)
You are welcome to still attach an action string to that Intent, if you want, but you can dump the <intent-filter> (routing will be based on the supplied component, in this case the Java class).
Only use an <intent-filter> when you are expecting the OS or third-party apps to initiate the Intent themselves (executing a PendingIntent that you created does not count).
The warning "Exported receiver does not require permission" means, You have an intent-filter with some action (which means by default you have android:exported="true" set and it can now receive broadcasts from ANY broadcasters outside of your application) Since it can receive broadcasts from ANY broadcasters outside of your application, it warns you by saying "Hey, are you sure ANY broadcaster can invoke you? In my opinion, it is better if you allow only those broadcasters to invoke you that has the permission you have set for this receiver through android:permission"
You can remove this warning by adding android:exported="false" to the receiver tag
If you do want to export your receiver to other processes, you can add your own permission definition in your android-manifest file for avoiding this warning, like
<permission
android:name="com.yourpage.permission.YOUR_PERMISSION"
android:protectionLevel="normal" />
<uses-permission
android:name="com.yourpage.permission.YOUR_PERMISSION" />
<receiver <!-- warning : Exported receiver does not require permission-->
android:name=".receivers.BatteryMonitoringReceiver"
android:permission="com.yourpage.permission.YOUR_PERMISSION"
android:enabled="false" >
<intent-filter>
<action android:name="#string/intent_action_setup_alarm" />
<action android:name="#string/intent_action_cancel_alarm" />
<action android:name="#string/intent_action_monitor" />
</intent-filter>
</receiver>
for more information, you can refer to http://developer.android.com/training/articles/security-tips.html
If, like me, you are here because your app built with a previous SDK version stopped working with more recent versions and you would like to fix it with minimal change, just add
android:exported=false
to the receiver tag in the manifest file. The solution by CommonsWare is obviously the one to go with for the long term but this fixes the issue temporarily if you are using custom intents and don't mean to export them.
Going by Lubo's way, you would need to export this custom permission, which would prompt the user before installation. That means the descriptive text for the permission needs to be well written so you don't end up scaring the user into changing his mind about installing the app. Also, it would need to be translated into all your target languages.
To hide this warning, add tools:ignore="ExportedReceiver" to the receiver:
<receiver
android:name=".MyReceiverIndentedForOtherAppsWithoutPermissions"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="com.my.app.CUSTOM_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
I want to learn how to create a main application and its associated key application. The problem is I don't know how to make key application broadcast mainapp.action.VALID into main app.
#MainApp
<permission
android:name="mainapp.permission.CHECK_RESULT"
android:protectionLevel="signature" />
<application>
<receiver
android:name=".ResponseReceiver"
android:permission="mainapp.permission.CHECK_RESULT" >
<intent-filter>
<action android:name="mainapp.action.CHECK_OK" />
</intent-filter>
</receiver>
#KeyApp
Intent i = new Intent();
i.setAction("mainapp.action.CHECK_OK");
context.sendBroadcast(i, "mainapp.permission.CHECK_RESULT");
The result is, intent is rejected: it requires mainapp.permission.CHECK_RESULT permission. But If I remove the permission, mainapp.receiver.ResponseReceiver can receive the intent and also can confirm that both app use the same signature.
What do I miss here?
As nandeesh indicates, you need the corresponding <uses-permission> element in your KeyApp, saying that KeyApp requests the mainapp.permission.CHECK_RESULT permission.
Also, AFAIK, your second parameter to sendBroadcast() will require MainApp to also have the <uses-permission> element for mainapp.permission.CHECK_RESULT. If that is not your intent (pun intended (nested pun intended (oh, no! infinite pun recursion!))), I would drop that second parameter on the sendBroadcast() call.
How do we specify in broadcast sending application that which application can receive this broadcast, and in receiving application that which particular application has the permission to send broadcast to its broadcast receiver...
I am new to android..I read the documentation etc on internet but couldn't find the syntax to specify these permissions.
To control who is able to receive the broadcast message, you can use the method sendBroadcast:
public abstract void sendBroadcast (Intent intent, String receiverPermission)
where you precise the name of the required permission. If the receiver does not declare this permission, it will not be able to get the message. For example, the broadcast sender can do:
Intent broadcast = new Intent(this, MyBroadcastReceiver.class);
sendBroadcast(broadcast, "andro.jf.mypermission");
In the manifest of the broadcast sender, a new permission should be declared:
<!-- Declaring the special permission -->
<permission android:name="andro.jf.mypermission"
android:label="my_permission"
android:protectionLevel="dangerous"></permission>
Then, in the application that is supposed to receive this broadcast, you have to declare this permission and say that you use it. In the manifest you can add:
<!-- I use the permission ! -->
<uses-permission android:name="andro.jf.mypermission"/>
and of course, you have to declare your broadcast receiver:
<receiver android:name="MyBroadcastReceiver" android:exported="true" />
You can have a look at this post for a complete example of a custom permission and also the android developer page about this. Be carefull with the order of installation of your apps because the one that defines the permission should be installed first.
If you want to restrict who only can send intents to your broadcast receiver, do it this way:
The broadcast receiver:
<manifest ...>
<!-- Permission declaration -->
<permission android:name="my.app.PERMISSION" />
<receiver
android:name="my.app.BroadcastReceiver"
android:permission="my.app.PERMISSION"> <!-- Permission enforcement for delivering intents to this receiver -->
<intent-filter>
<action android:name="my.app.Action" />
</intent-filter>
</receiver>
...
</manifest>
The broadcast sender:
<manifest ...>
<!-- We declare we own the permission to send broadcast to the above receiver -->
<uses-permission android:name="my.app.PERMISSION" />
...
</manifest>
Sending broadcast from the sender Activity to the receiver:
Intent intent = new Intent();
intent.setAction("my.app.Action");
activity.sendBroadcast(intent);
If you declare the permission like this:
<permission android:protectionLevel="signature" android:name="my.app.PERMISSION" />
Then the sender will be able to use this permission and send broadcasts to receiver only when both the sender and the receiver apps are signed by the same developer certificate.
Declare permission
First you need declare your permission in your AndroidManifest.xml
<permission android:name="YOUR_PERMISSION_STRING" android:protectionLevel="signature"/>
<uses-permission android:name="com.codylab.photogallery.PRIVATE"/>
the android:name value is used as permission value and will used later.
Usage
There are two kinds of permission usages related to broadcast receiver:
(1) Control which application can receive your broadcast:
String PERMISSION_STRING_PRIVATE_RECEIVER = "YOU_NEED_THIS_TO_RECEIVE_THIS_BROADCAST"
sendBroadcast(intent, PERMISSION_STRING_PRIVATE_RECEIVER);
With this usage, you can control only authorized application can handle the broadcast you sent.
(2) Only handle the broadcasts have the specified permission
String PERMISSION_STRING_PRIVATE_BROADCASTER = "ONLY HANDLE BROADCASTS WITH THIS PERMISSION"
IntentFilter filter = new IntentFilter(ACTION_SAMPLE);
registerReceiver(mReceiver, filter, PERMISSION_STRING_PRIVATE_BROADCASTER, null);
With this usage, you can make sure that the broadcaster is authorized.
use an intent filter in receiver tag in manifest
<receiver
android:name="Your receiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="action"/>
<category android:name="category" />
</intent-filter>
</receiver>
To send broadcast to app
Intent intent = new Intent();
intent.setAction("use same action in receiver");
intent.addcategory("use same category in receiver");
context.sendBroadcast(intent);
After half day search and test, based on #JFL's answer, I find the sender app must add both <permission> tag and <uses-permission> tag, then the receiver can receive the broadcast with permission. Otherwise, the receiver app won't receive the broadcast.
I have implemented simple message(xmpp protocol) application using smack api.there are number activities which are receiving notification when incoming message comes.now i want to notify my application when the incoming message comes even the application is not running.By reading documentation i know that this is achieved by Broadcast receiver.But how to adopt this to my application.
You don't need the broadcast receiver to do this.
In you androidmanifest.xml for eg: consider this activity.
<activity android:name=".activity.message"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleInstance">
<intent-filter>
<action android:value="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</activity>
Once you add the intent to the activity's intent filter list in android.xml,whenever that intent is thrown your activity will be invoked irrespective of whether it is open or not.
Here the intent you would want to add to listen for incoming messages would be
<action android:value="android.provider.Telephony.SMS_RECEIVED" />
I think you also need to have permissions for this so add this also to your manifest.xml
<uses-permission id="android.permission.RECEIVE_SMS" />