当我尝试打开文件时,应用程序崩溃了。它在 Android Nougat 下工作,但在 Android Nougat 上它会崩溃。只有当我尝试从 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
日志:
android.os.FileUriExposedException: file:///storage/emulated/0/test.txt 通过 Intent.getData() 暴露在应用程序之外
编辑:
以 Android Nougat 为目标时,file://不再允许使用 URI。我们应该改用content://URI。但是,我的应用程序需要在根目录中打开文件。有任何想法吗?
file://
content://
如果您的targetSdkVersion >= 24,那么我们必须使用FileProvider类来授予对特定文件或文件夹的访问权限,以使其他应用程序可以访问它们。我们创建自己的继承类FileProvider,以确保我们的 FileProvider 不会与在导入依赖项中声明的 FileProvider 冲突,如此处所述。
targetSdkVersion >= 24
FileProvider
用 URI替换file://URI 的步骤content://:
在标签下添加 FileProvider<provider>标签。为属性指定唯一权限以避免冲突,导入的依赖项可能会指定其他常用权限。AndroidManifest.xml``<application>``android:authorities``${applicationId}.provider
<provider>
AndroidManifest.xml``<application>``android:authorities``${applicationId}.provider
<?xml version=”1.0” encoding=”utf-8”?> <manifest xmlns:android="http://schemas.android.com/apk/res/android” … <application …
然后在文件夹中创建一个provider_paths.xml文件res/xml。如果文件夹尚不存在,则可能需要创建它。该文件的内容如下所示。它描述了我们希望在根文件夹中共享(path=".")对名为 external_files 的外部存储的访问。
provider_paths.xml
res/xml
(path=".")
<?xml version=”1.0” encoding=”utf-8”?>
最后一步是更改下面的代码行
Uri photoURI = Uri.fromFile(createImageFile());
到
Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);