可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have two apps : app1 and app2.
App2 has :
paths.xml :
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 ?
回答1:
Turns out the only way to solve this is to grant permissions to all of the packages that might need it, like this:
List 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); }
回答2:
First, I would try switching away from grantUriPermission() and simply put the FLAG_GRANT_READ_URI_PERMISSION on the Intent itself via addFlags() or setFlag().
If for some reason that does not work, you could try moving your getCallingUid() logic into onCreate() instead of wherever you have it, and see if you can find out the actual "caller" there.
回答3:
Just add setData(contentUri); and based on requirement add addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); or addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
This solves the java.lang.SecurityException: Permission Denial
Verified.
This is done as per https://developer.android.com/reference/android/support/v4/content/FileProvider.html#Permissions
回答4:
How you capture image using camera on Nougat
,and kit kat and marshmallow follow these steps. First of all ad tag provider under application tag in MainfestFile.
create a file name with (provider_paths.xml) under res folder 
I have solved this issue it comes on kit kitkat version
private void takePicture() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { Uri photoURI = null; try { File photoFile = createImageFileWith(); path = photoFile.getAbsolutePath(); photoURI = FileProvider.getUriForFile(MainActivity.this, getString(R.string.file_provider_authority), photoFile); } catch (IOException ex) { Log.e("TakePicture", ex.getMessage()); } takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); if (Build.VERSION.SDK_INT
回答5:
Thanks @CommonsWare for his advice.
I problem was with the calling package. For some reason, Binder.callingUid() and getPackageManager().getNameForUid(uid) is giving me package name of App2 instead of App1.
I tried calling it in App2's onCreate as well as onResume, but no joy.
I used the following to solve it :
getApplicationContext().grantUriPermission(getCallingPackage(), contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
Turns out, activity has dedicated API for this. See here.
回答6:
I solved the problem that way:
Intent sIntent = new Intent("com.appname.ACTION_RETURN_FILE").setData(uri); List resInfoList = activity.getPackageManager().queryIntentActivities(sIntent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { activity.grantUriPermission(FILE_PROVIDER_ID, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } sIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); activity.setResult(RESULT_OK, sIntent);
回答7:
Android
There's a great article by Lorenzo Quiroli that solves this issues 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
I tested this on API 17 and it worked great. Couldn't find a solution anywhere that worked.
回答8:
You need to set permission of specific package name, after that you can able to access it..
context.grantUriPermission("com.android.App1.app", fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
回答9:
java.lang.SecurityException: Permission Denial: ...
See https://stackoverflow.com/a/44455957/966789 (Android added new permission model for Android 6.0 Marshmallow)
To request permissions at run-time:
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; requestPermissions(permissions, WRITE_REQUEST_CODE);