flutter_share icon indicating copy to clipboard operation
flutter_share copied to clipboard

java.lang.SecurityException: Permission Denial

Open BYVoid opened this issue 4 years ago • 19 comments

I added androidx.core.content.FileProvider and provider_paths.xml, but still encountered such an error:

E/DatabaseUtils(22545): Writing exception to parcel
E/DatabaseUtils(22545): java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://com.example.app.provider/external_files/Android/data/com.example.app/files/test.json from pid=22857, uid=1000 requires the provider be exported, or grantUriPermission()
E/DatabaseUtils(22545): 	at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:729)
E/DatabaseUtils(22545): 	at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:602)
E/DatabaseUtils(22545): 	at android.content.ContentProvider$Transport.query(ContentProvider.java:231)
E/DatabaseUtils(22545): 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:104)
E/DatabaseUtils(22545): 	at android.os.Binder.execTransactInternal(Binder.java:1021)
E/DatabaseUtils(22545): 	at android.os.Binder.execTransact(Binder.java:994)

BYVoid avatar Mar 05 '20 13:03 BYVoid

Are you still getting this error?

lubritto avatar Mar 31 '20 13:03 lubritto

@lubritto I'm seeing this exception on the console, but the functionality seems to work fine. Is this something that has to be fixed on the plugin side?

E/DatabaseUtils(11210): java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://filePath from pid=16973, uid=1000 requires the provider be exported, or grantUriPermission()
E/DatabaseUtils(11210): 	at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:729)
E/DatabaseUtils(11210): 	at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:602)
E/DatabaseUtils(11210): 	at android.content.ContentProvider$Transport.query(ContentProvider.java:231)
E/DatabaseUtils(11210): 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:104)
E/DatabaseUtils(11210): 	at android.os.Binder.execTransactInternal(Binder.java:1021)
E/DatabaseUtils(11210): 	at android.os.Binder.execTransact(Binder.java:994)

JenniferJesuraj avatar Apr 06 '20 16:04 JenniferJesuraj

I get it too on Android 10

longravuth avatar Apr 14 '20 21:04 longravuth

Still reproducible.

BYVoid avatar Apr 15 '20 06:04 BYVoid

I have the same issue but the feature works, i can share no problem but i get that warning in the console.

marcLeeroy avatar Jun 03 '20 12:06 marcLeeroy

I am seeing the same error:

For reference I found:

https://stackoverflow.com/questions/45893294/permission-denial-with-file-provider-through-intent

and

https://stackoverflow.com/questions/57689792/permission-denial-while-sharing-file-with-fileprovider

Specifically, the stackoverflow solution involves adding:

Intent chooser = Intent.createChooser(intentShareFile, "Share File");

List<ResolveInfo> resInfoList = this.getPackageManager().queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY);

for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    this.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

startActivity(chooser);

I am going to create a fork and see if this solves the problem. Will open a pull request if it does.

vertis avatar Jun 23 '20 12:06 vertis

If anyone is interested in using this bugfix until it is merged you can do so by adding the following to pubspec.yaml:

flutter_share:
    git:
      url: https://github.com/vertis/flutter_share.git

Just make sure to change it back once it's merged. I do not intend to keep my fork updated.

vertis avatar Jun 23 '20 13:06 vertis

Same issue.

rjaylwar avatar Jul 02 '20 23:07 rjaylwar

I see the error logged in the console as well, although the feature seems to work. Would like for the fix to be merged in

mobabur94 avatar Jul 03 '20 22:07 mobabur94

https://stackoverflow.com/a/65342993/14844728

Intent sharableIntent = new Intent();
sharableIntent.setAction(Intent.ACTION_SEND);
sharableIntent.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION );

Uri imageUri = Uri.parse(ImgLoc);
File imageFile = new File(String.valueOf(imageUri));
Uri UriImage = FileProvider.getUriForFile(context, Author, imageFile);

sharableIntent.setType("image/*");
sharableIntent.putExtra(Intent.EXTRA_STREAM, UriImage);
sharableIntent.putExtra(Intent.EXTRA_TITLE, title);
sharableIntent.putExtra(Intent.EXTRA_TEXT, body);

Intent chooser = Intent.createChooser(sharableIntent, "Chooser Title");
chooser.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
context.startActivity(chooser);

LokeshNakka avatar Dec 21 '20 07:12 LokeshNakka

I get it too on Android 10

i got it on Android 11, not on Android 10

VivekThummar52 avatar Jun 10 '21 05:06 VivekThummar52

I am getting in Android 10 and Android 12. (Not checked for Android 11)

shubhamnandanwar avatar Jul 16 '21 13:07 shubhamnandanwar

@VivekThummar52 @shubhamnandanwar Did you find a solution?

manwithsteelnerves avatar Aug 09 '21 06:08 manwithsteelnerves

@manwithsteelnerves As of i know and i have tried, given solution worked for me, please try this :

try {
                    Uri uri = imagesList.get(position).getUri();
                    if (uri != null) {
                        String path = FileUtils.getPath(this, uri);
                        if (path == null) {
                            Toast.makeText(this, "Error getting Image Path", Toast.LENGTH_SHORT).show();
                            return false;
                        }
                        File shareFile = new File(path);
                        Uri shareUri = null;
                        try {
                            shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", shareFile); // ".provider" or ".fileprovider" or whatever you have mentioned in manifest file
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        if (shareUri != null) {
                            Intent shareIntent = getShareIntent(null, shareUri, "image/*");
                            startActivity(Intent.createChooser(shareIntent, "Share Image Using"));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

public Intent getShareIntent(String packagename, Uri uri, String type) {
    Intent intent = new Intent("android.intent.action.SEND");
    if (packagename != null) {
        intent.setPackage(packagename);
    }

    if (Build.VERSION.SDK_INT > 23) {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setDataAndType(uri, type);
        intent.putExtra(Intent.EXTRA_STREAM, uri);
    } else {
        intent.setType(type);
    }

    intent.putExtra(Intent.EXTRA_SUBJECT, "Created by Your App Name");
    intent.putExtra(Intent.EXTRA_TEXT, Helper.shareText);
    intent.putExtra("android.intent.extra.STREAM", uri);
    return intent;
}

And tell me if this will work for you or not..

VivekThummar52 avatar Aug 09 '21 07:08 VivekThummar52

Even I'm granting the read uri permission but not working for multiple files

It started working after adding the uri permission flag on the intent chooser too for all the attachments (uris).

List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(chooser, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            for (FileAttachment each:attachments) {
                context.grantUriPermission(packageName, each.uri,  Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
        }

manwithsteelnerves avatar Aug 09 '21 19:08 manwithsteelnerves

@manwithsteelnerves in line - intent.putExtra(Intent.EXTRA_STREAM, uri);, i think you can also set list of String or Uri, you have tried it or not??

if not then look at this answer - https://stackoverflow.com/a/15577579

VivekThummar52 avatar Aug 10 '21 04:08 VivekThummar52

@manwithsteelnerves in line - intent.putExtra(Intent.EXTRA_STREAM, uri);, i think you can also set list of String or Uri, you have tried it or not??

if not then look at this answer - https://stackoverflow.com/a/15577579

Yes. I'm currently setting the array of streams(uri) only. But still it expects me to add the read permission flags on "chooser" intent by going through all of the matching packages (note you may need to add QUERY_ALL_PACKAGES or tag if >= API 30 is your target api)

manwithsteelnerves avatar Aug 10 '21 06:08 manwithsteelnerves

Hey,

I was using scoped storage and I figured it's impossible for me to share that particular image (please correct me if I am wrong). I found a thread in which the developer was creating a cache image in the scoped folder and was sharing the cached image. The developer also hardcoded the image name, so whenever a user shares a new image, the previous cache image gets overwritten. Unfortunately, I couldn't find that thread again but here's the code -


val cachePath = File(externalCacheDir, "my_images/")
cachePath.mkdirs()
val bitmap = loadImageFromStorage(currentQuote.bookId)
val file = File(cachePath, "readmore-cache.png")
val fileOutputStream: FileOutputStream
try {
	fileOutputStream = FileOutputStream(file)
	bitmap?.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
	fileOutputStream.flush()
	fileOutputStream.close()
} catch (e: FileNotFoundException) {
	e.printStackTrace()
} catch (e: IOException) {
	e.printStackTrace()
}
val cacheImageUri: Uri = FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", file)
			
val intent = Intent(Intent.ACTION_SEND).apply {
	clipData = ClipData.newRawUri(null, cacheImageUri)
	putExtra(Intent.EXTRA_STREAM, cacheImageUri)
	type = "image/ *"
	addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(Intent.createChooser(intent, null))


I have tested it in Android 12 and 10 and it's working fine.

shubhamnandanwar avatar Aug 10 '21 06:08 shubhamnandanwar

I am still getting the error. Is there an update in the pipe?

nicop2000 avatar Feb 23 '22 22:02 nicop2000