安卓操作系统。FileUriExposedException:file:///storage/emulated/0/test.txt通过意图暴露在应用程序之外。getData()
当我试图打开文件时,应用程序正在崩溃。它在安卓牛轧糖下工作,但在安卓牛轧糖上崩溃。只有当我试图从SD卡而不是系统分区打开文件时,它才会崩溃。一些许可问题
示例代码:
File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line
日志:
安卓.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
编辑:
针对Android Nougat时,不再允许使用^uri。我们应该改用content://
uri。但是,我的应用程序需要打开根目录中的文件。有什么想法吗
# 1 楼答案
如果您的
targetSdkVersion >= 24
,那么我们必须使用FileProvider
类来授予对特定文件或文件夹的访问权限,以便其他应用程序可以访问这些文件或文件夹。我们创建自己的类继承FileProvider
,以确保我们的文件提供程序不会与here所述的导入依赖项中声明的文件提供程序冲突用
content://
URI替换file://
URI的步骤:<application>
标记下的AndroidManifest.xml
中添加一个FileProvider<provider>
标记。为android:authorities
属性指定唯一的权限为避免冲突,导入的依赖项可能会指定${applicationId}.provider
和其他常用的权限李>res/xml
文件夹中创建一个provider_paths.xml
文件。如果文件夹尚不存在,则可能需要创建该文件夹。该文件的内容如下所示。它描述了我们希望共享对根文件夹(path=".")
中名为External\u files的外部存储的访问李>最后一步是在中更改下面的代码行
到
编辑:如果您打算让系统打开您的文件,您可能需要添加以下代码行:
请参阅已解释的完整代码和解决方案here.
# 2 楼答案
首先,您需要向AndroidManifest添加一个提供者
现在在xml资源文件夹中创建一个文件(如果使用android studio,可以在突出显示文件路径后点击Alt+Enter并选择创建xml资源选项)
在文件路径文件中的下一步,输入
此示例适用于外部路径,您可以参考here了解更多选项。 这将允许您共享该文件夹及其子文件夹中的文件
现在只剩下创建如下意图:
编辑:我在文件路径中添加了sd卡的根文件夹。我已经测试了这段代码,它确实有效
# 3 楼答案
如果您的应用程序以API 24+为目标,并且您仍然希望/需要使用file://intents,则可以使用hacky方法禁用运行时检查:
方法
StrictMode.disableDeathOnFileUriExposure
被隐藏并记录为:问题是,我的应用程序并不是跛脚的,而是不想因为使用content://意图而瘫痪,而这一点在很多应用程序中是不理解的。例如,使用content://scheme打开mp3文件提供的应用程序比使用file://scheme打开mp3文件提供的应用程序少得多。我不想通过限制我的应用程序的功能来为谷歌的设计缺陷买单
谷歌希望开发者使用content scheme,但系统并没有为此做好准备,多年来,应用程序使用的是文件而不是“内容”,文件可以编辑和保存,而通过content scheme提供的文件则不能(可以吗?)
# 4 楼答案
如果您的} ^{} values in ^{} on Android 7.0+ devices
targetSdkVersion
为24或更高,you can not use ^{你的选择是:
将
targetSdkVersion
降到23或更低,或将您的内容放入内部存储,然后use ^{} 有选择地将其提供给其他应用程序
例如:
(从this sample project)
# 5 楼答案
除了使用
FileProvider
的解决方案之外,还有另一种解决方法。简而言之在
Application.onCreate()
中。这样VM就会忽略文件URI
暴露方法
启用文件暴露检查,这也是未设置VmPolicy时的默认行为
我遇到了一个问题,如果我使用}发送东西,一些应用程序就无法理解它。并且不允许降级
content://
{target SDK
版本。在这种情况下,我的解决方案很有用更新:
如注释中所述,StrictMode是诊断工具,不应用于此问题。当我一年前发布这个答案时,许多应用程序只能接收文件URI。当我试图向它们发送文件提供程序uri时,它们就崩溃了。现在大多数应用程序都修复了这个问题,所以我们应该使用FileProvider解决方案
# 6 楼答案
如果
targetSdkVersion
高于24,则FileProvider用于授予访问权限创建一个xml文件(路径:res\xml)提供程序路径。xml
在AndroidManifest.xml
如果使用的是androidx,则文件提供程序路径应为:
和替换
到
编辑:在使用
Intent
包含URI时,请确保添加以下行:你可以走了。希望能有帮助