I have two apps : app1 and app2.
App2 has :
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.provider.ImageSharing"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
paths.xml :
<paths>
<files-path name="my_images" path="images/"/>
</paths>
App2 receives request in its Activity from App1 to get URI for an image. The App2 Activity does the following once URI is decided :
Intent intent = new Intent();
intent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
int uid = Binder.getCallingUid();
String callingPackage = getPackageManager().getNameForUid(uid);
getApplicationContext().grantUriPermission(callingPackage, contentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
setResult(Activity.RESULT_OK, intent);
finish();
On receiving the result back from App2, App1 does the following :
Uri imageUri = data.getData();
if(imageUri != null) {
ImageView iv = (ImageView) layoutView.findViewById(R.id.imageReceived);
iv.setImageURI(imageUri);
}
In App1, on returning from App2, I get the following exception :
java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{52a99eb0 3493:com.android.App1.app/u0a57} (pid=3493, uid=10057) that is not exported from uid 10058
What am I doing wrong ?
FileProvider is a special subclass of ContentProvider that facilitates secure sharing of files associated with an app by creating a content:// Uri for a file instead of a file:/// Uri . A content URI allows you to grant read and write access using temporary access permissions.
To make FileProvider work follow these three steps: Define the FileProvider in your AndroidManifest file. Create an XML file that contains all paths that the FileProvider will share with other applications. Bundle a valid URI in the Intent and activate it.
You can try this solution for get real path from file provider URI. First you need to define file provider path file as following. Declare file provider in AndroidMenifest. xml as following.
Turns out the only way to solve this is to grant permissions to all of the packages that might need it, like this:
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
There's a great article by Lorenzo Quiroli that solves this issue for older Android versions.
He discovered that you need to manually set the ClipData of the Intent and set the permissions for it, like so:
if ( Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP ) {
takePictureIntent.setClipData( ClipData.newRawUri( "", photoURI ) );
takePictureIntent.addFlags( Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION );
}
I tested this on API 17 and it worked great. Couldn't find a solution anywhere that worked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With