尝试使用 Intent 发送文件时出现 android.os.StrictMode.onFileUriExposed
异常。据我了解,这是因为我的目标是 24> 并且不再支持 file://
,应该使用 content://
。
首先我想说我见过类似的问题,例如 this , this我还看到了this博客文章。
但问题是,所有帖子在拍照时都会引用 URI,在我的例子中,文件已使用 Uri 成功保存,现在我想使用 Intent 发送图像,如下所示:
shareBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse("file://" + directoryToStore + "/" + filename);
//the Uri above - file:///storage/emulated/0/Android/data/myPackageName/files/SavedImages/test.jpeg
sharingIntent.setType("image/jpeg");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, "Share image using"));
}
});
通过执行上述操作,我只会在某些运行 19> 的设备上发生崩溃。在我的 Samsung J7Pro (Android 7.0 API 24) 上进行测试,我没有遇到崩溃。
我看到其中一些答案说我可以使用:
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
但这不是首选方式。
所以,我的问题是。当目标为 24> 时,我应该如何处理发送文件。我是否应该执行 if/else 语句检查版本,例如 if (Build.VERSION.SDK_INT >= 19) {
,然后对运行 <24 的设备使用普通 Uri 以及如何更改 file ://
到 content://
?我也不明白为什么崩溃只发生在某些设备上。
编辑1:
我已经完成了下面建议的答案,但文件并未按 Intent 传递,相反,当我尝试发送电子邮件时,我收到一个 Toast
说 无法附加文件
图像。
最佳答案
从应用程序共享文件的正确方法是 content provider
,具体来说FileProvider .
添加您的FileProvider
到 AnroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.MyFileProvider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/shared_paths"/>
</provider>
接下来,通过添加 xml 资源来添加引用的资源(Android Studio:右键单击“app”-> 新建 -> 文件夹 -> XML 资源 fodler)
然后,在这个新文件夹中创建一个名为 shared_paths.xml
的 xml 文件。 (应与 AndroidManifest.xml 中的值匹配)。 shared_paths.xml
的内容:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="SavedImages" path="SavedImages/"/>
</paths>
编辑:从 <files-path ../>
更改元素类型至<external-path .. />
每documentation 。
重要提示:更改 path
属性以满足您的需求。
最后更改您的代码如下:
shareBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = FileProvider.getUriForFile(context, context.getPackageName() + ".MyFileProvider", new File(directoryToStore, filename))
//the Uri above - file:///storage/emulated/0/Android/data/myPackageName/files/SavedImages/test.jpeg
sharingIntent.setType("image/jpeg");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent chooserIntent = Intent.createChooser(sharingIntent, "Share image using");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(chooserIntent);
}
});
关于java - Intent.ACTION_SEND 定位 API 级别 24+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51462659/