小编典典

android.os.FileUriExposedException: file:///storage/emulated/0/test.txt 通过Intent.getData() 暴露在应用程序之外

all

当我尝试打开文件时,应用程序崩溃了。它在 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。但是,我的应用程序需要在根目录中打开文件。有任何想法吗?


阅读 201

收藏
2022-03-01

共1个答案

小编典典

如果您的targetSdkVersion >= 24,那么我们必须使用FileProvider类来授予对特定文件或文件夹的访问权限,以使其他应用程序可以访问它们。我们创建自己的继承类FileProvider,以确保我们的
FileProvider 不会与在导入依赖项中声明的 FileProvider
冲突,如此处所述

用 URI替换file://URI 的步骤content://

  • 在标签下添加 FileProvider<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 的外部存储的访问。

    <?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);
    
2022-03-01