Android使用ACTION_SEND实现图文分享仅部分应用生效的问题求助
问题根源
你使用android.resource://格式的Uri执行分享时,绝大多数第三方应用没有权限访问你应用内部的res目录资源,且FLAG_GRANT_READ_URI_PERMISSION权限标记仅对content://类型的Uri生效,因此会出现部分应用适配、部分应用报错的问题。
解决方案
按照安卓官方规范,使用FileProvider生成可授权访问的content://类型Uri完成分享,步骤如下:
1. 配置FileProvider
在AndroidManifest.xml的<application>标签内添加如下配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
如果你使用的是Support库而非AndroidX,将
androidx.core.content.FileProvider替换为android.support.v4.content.FileProvider即可。
2. 配置文件访问路径
在res/xml目录下新建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="shared_images" path="images/"/> </paths>
该配置表示允许分享应用缓存目录下images文件夹内的文件。
3. 替换分享逻辑
先将raw目录下的图片复制到外部可访问的缓存目录,再生成对应Uri执行分享,修改后代码如下:
// 创建缓存目录 File cachePath = new File(getActivity().getCacheDir(), "images"); cachePath.mkdirs(); File shareImageFile = new File(cachePath, "share_image.jpg"); // 将raw资源复制到缓存文件 try { InputStream inputStream = getActivity().getResources().openRawResource(R.raw.loremipsum2); FileOutputStream outputStream = new FileOutputStream(shareImageFile); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } // 生成content类型Uri Uri shareUri = FileProvider.getUriForFile( getActivity(), getActivity().getPackageName() + ".fileprovider", shareImageFile ); // 执行分享逻辑 String message = "hello world"; Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, message); intent.putExtra(Intent.EXTRA_STREAM, shareUri); intent.setType("image/jpeg"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 用选择器包装提升兼容性 startActivity(Intent.createChooser(intent, "分享到"));
注意事项
- 确保Manifest中配置的
authorities值与FileProvider.getUriForFile传入的第二个参数完全一致 - 如果你的资源文件不是JPG格式,需要同步修改文件后缀名和
setType对应的MIME类型 - 不需要额外申请存储权限,应用私有缓存目录的访问不需要权限声明
内容的提问来源于stack exchange,提问作者tremon
相关产品推荐
相关产品推荐

