0

I have two apps where the second one has a broadcast receiver declared in its manifest.xml

    <receiver android:name="com.company.app2.MyBroadcastReceiver" >
        <intent-filter>
            <action android:name="com.company.ACTION_CUSTOM" />
            <category android:name="android.intent.category.DEFAULT" /> 
        </intent-filter>
    </receiver>

From the other app I send broadcast this way

Intent intent = new Intent();
intent.setAction("com.company.ACTION_CUSTOM");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//if I decomment the next line the BroadcastReceiver will not receive the broadcast 
//intent.setData(fileUri);

Please guys tell me why I can't receive broadcasts when I setData ...Thanks!

M'hamed
  • 2,508
  • 3
  • 24
  • 41

2 Answers2

3

When finding a matching component for an implicit intent, both the action, category, data and type are used, i.e., all of them must match.

This means that an intent with only an action will match a receiver with only an action, while an intent with an action and data will only match a receiver with that action and a <data> element matching the data URI.

Note that extras are never used for matching, which is why when you put your data as an extra instead of using setData(), you did match your action-only receiver.

Example:

Intent intent = new Intent();
intent.setAction("com.company.ACTION_CUSTOM");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("file://somefile.jpg"));

This will for example match a receiver with the following intent filter:

<receiver android:name="com.company.app2.MyBroadcastReceiver" >
    <intent-filter>
        <action android:name="com.company.ACTION_CUSTOM" />
        <category android:name="android.intent.category.DEFAULT" /> 
        <data android:scheme="file" />
    </intent-filter>
</receiver>

...because the action, category and data all match. If the intent filter were to not have any <data> element, it would only match intents also not having any data.

It's quite common to skip the data for intents using custom actions, especially if used only internally within an app. However, for intents using standard actions such as android.intent.action.VIEW, data (or type) is critical to make any sensible matching (imagine the chaos if an android.intent.action.VIEW intent with an image URI as the data would be matched by all components supporting android.intent.action.VIEW regardless of the type of data!)

JHH
  • 8,567
  • 8
  • 47
  • 91
0

From the documentation:

The type of data supplied is generally dictated by the intent's action. For example, if the action is ACTION_EDIT, the data should contain the URI of the document to edit.

So in your case you can simply pass the uri with intent extras.

TOMKA
  • 1,096
  • 13
  • 24
  • I set the uri as an extra and it did work, The Broadcast Receiver has received the intent BUT I couldn't read the file from the uri. I got this exception java.lang.SecurityException: Uid 10068 does not have permission to uri content://com.company.app1.fileprovider/file – M'hamed Jun 05 '14 at 19:07
  • Take a look [here](http://stackoverflow.com/questions/21275898/securityexception-with-granturipermission-when-sharing-a-file-with-fileprovider) You probably need to set your manifest permissions right. – TOMKA Jun 07 '14 at 07:22
  • 1
    This does in no way answer the question. The reason the receiver is not invoked is because an intent filter without data does not match an intent with data, as described in my answer below. – JHH Oct 11 '17 at 11:06