I am trying to test whether URI permissions work with Broadcast.
The first app I have has the following code in an activity :
Intent intent = new Intent("com.android.testintent.app.bcast");
intent.setData(contentUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendBroadcast(intent);
The content URI is obtained from a FileProvider.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.provider.DataSharing"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
contentUri = FileProvider.getUriForFile(getApplicationContext(),
"com.android.provider.DataSharing", /* file's path */);
// file's path is correct - I have tested it with activity
In the app receiving the broadcast :
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.android.testintent.app.bcast" />
</intent-filter>
</receiver>
The receiver code - onReceive() :
Toast.makeText(context, "Bcast - received", Toast.LENGTH_LONG).show();
Uri uri = intent.getData();
if(uri != null) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
}
catch (Exception e) {
Log.d("TEST", "Bcast - exception : " + e);
}
}
When I pass the URI as null from the first app, the broadcast reaches the receiver and I can see the toast message. However, when the URI is not null, my receiver does not even receive the broadcast.
Can anyone point out the reason for this behavior ?
Edit :
I edited the Receiver :
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.android.teachintent.app.bcast1" />
<data android:mimeType="image/jpeg" />
</intent-filter>
</receiver>
I added the mime type
. I did this based on the rule (see here)
An intent that contains both a URI and a MIME type (either explicit or
inferable from the URI) passes the MIME type part of the test only if
that type matches a type listed in the filter. It passes the URI
part of the test either if its URI matches a URI in the filter or if
it has a content: or file: URI and the filter does not specify a URI.
In other words, a component is presumed to support content: and file:
data if its filter lists only a MIME type.
Now I get the exception in the receiver :
D/TEST﹕ Bcast - exception : java.lang.SecurityException: Permission Denial:
opening provider android.support.v4.content.FileProvider from
ProcessRecord{529a7b60 1593:com.android.testintent.app/u0a55}
(pid=1593, uid=10055) that is not exported from uid 10059
If I try to export the FileProvider, Android throws an exception saying Providers are not allowed to be exported.
What can I do to resolve this ?
The reason is that you are not matching the <intent-filter>
. Your <intent-filter>
is only matching on the action string. You also need to qualify for your Uri
, via a <data>
element indicating that you support the the right MIME type.content
scheme