Android 11及以上版本中通过Intent分享应用私有文件时权限拒绝问题求助
Hey there, let's tackle this permission issue you're facing! The error message you're seeing happens because even though you added the FLAG_GRANT_READ_URI_PERMISSION flag, the permission isn't being correctly passed to the target app when using Intent.createChooser(). Plus, there are a couple of missing pieces in your Intent setup that are causing problems.
Why This Happens
- Incorrect Intent Setup: You commented out the
Intent.ACTION_SENDinitialization, and you're usingdata = imageUriinstead of the standardEXTRA_STREAMfor sharing content. Most share targets expectEXTRA_STREAMfor media files, not thedatafield. - Permission Forwarding: When using
createChooser(), the system's chooser app acts as an intermediary. The permission flag you set on your original Intent might not automatically propagate to the app the user selects.
Step-by-Step Fix
1. Correct Your Share Intent Setup
First, properly initialize the share Intent with the right action, MIME type, and use EXTRA_STREAM to pass the URI. Here's the revised code:
val imagePath = File(this.filesDir, "photos") val newImageFile = File(imagePath, currentImage.imageName) val imageUri = FileProvider.getUriForFile(this, "$packageName.provider", newImageFile) // Initialize the share intent correctly val shareContentIntent = Intent(Intent.ACTION_SEND).apply { // Set the MIME type to match your image type = "image/*" // Use EXTRA_STREAM to pass the image URI (standard for ACTION_SEND) putExtra(Intent.EXTRA_STREAM, imageUri) // Grant read permission to the target app addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } // Launch the chooser startActivity(Intent.createChooser(shareContentIntent, "Share Image"))
2. Optional: Explicitly Grant Permissions to All Target Apps
If some apps still refuse to read the image (a rare edge case), you can explicitly grant the URI permission to every app that can handle your share Intent. Add this code before launching the chooser:
// Get all apps that can handle the share intent val resInfoList = packageManager.queryIntentActivities(shareContentIntent, PackageManager.MATCH_DEFAULT_ONLY) // Grant read permission to each of these apps for (resolveInfo in resInfoList) { val packageName = resolveInfo.activityInfo.packageName grantUriPermission( packageName, imageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION ) }
Verify Your Existing Configurations
Your AndroidManifest.xml and file_paths.xml look correct, but just double-check:
- The
android:authoritiesin your provider matches the one you pass toFileProvider.getUriForFile()(it does in your code:$packageName.provider) - The
files-pathinfile_paths.xmlcorrectly points to yourphotosdirectory inside app-specific files (which it does:path="photos/")
Why This Works
- Using
EXTRA_STREAMinstead ofdataaligns with Android's sharing conventions for media files, ensuring apps recognize the content you're sending. - Explicitly granting permissions via
grantUriPermission()guarantees that every potential share target has access to the URI, bypassing any issues with permission propagation through the chooser.
Give this a try—your share functionality should now work without needing to move images to a public directory!
内容的提问来源于stack exchange,提问作者Waqas Younis

