android.os.FileUriExposedException: file:///storage/emulated/0/test.txt 通过 Intent.getData() 暴露在应用程序之外 [英] android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

查看:90
本文介绍了android.os.FileUriExposedException: file:///storage/emulated/0/test.txt 通过 Intent.getData() 暴露在应用程序之外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试打开文件时应用程序崩溃.它在 Android Nougat 下运行,但在 Android Nougat 上它会崩溃.它只会在我尝试从 SD 卡而不是从系统分区打开文件时崩溃.一些权限问题?

The app is crashing when I'm trying to open a file. It works below Android Nougat, but on Android Nougat it crashes. It only crashes when I try to open a file from the SD card, not from the system partition. Some permission problem?

示例代码:

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.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

定位到 Android Nougat 时,不再允许 file:// URI.我们应该改用 content:// URI.但是,我的应用程序需要打开根目录中的文件.有什么想法吗?

When targeting Android Nougat, file:// URIs are not allowed anymore. We should use content:// URIs instead. However, my app needs to open files in root directories. Any ideas?

推荐答案

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

If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps. We create our own class inheriting FileProvider in order to make sure our FileProvider doesn't conflict with FileProviders declared in imported dependencies as described here.

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

Steps to replace file:// URI with content:// URI:

  • 标签下的 AndroidManifest.xml 中添加 FileProvider 标签.为 android:authorities 属性指定唯一权限以避免冲突,导入的依赖项可能指定 ${applicationId}.provider 和其他常用权限.
  • Add a FileProvider <provider> tag in AndroidManifest.xml under <application> tag. Specify a unique authority for the android:authorities attribute to avoid conflicts, imported dependencies might specify ${applicationId}.provider and other commonly used authorities.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
    </application>
</manifest>

  • 然后在 res/xml 文件夹中创建一个 provider_paths.xml 文件.如果文件夹尚不存在,则可能需要创建该文件夹.该文件的内容如下所示.它描述了我们希望共享对根文件夹 (path=.") 中名为 external_files 的外部存储的访问权限.
    • Then create a provider_paths.xml file in res/xml folder. A folder may be needed to be created if it doesn't exist yet. The content of the file is shown below. It describes that we would like to share access to the External Storage at root folder (path=".") with the name external_files.
    • <?xml version="1.0" encoding="utf-8"?>
      <paths>
          <external-path name="external_files" path="."/>
      </paths>
      

      • 最后一步是更改下面的代码行

        • The final step is to change the line of code below in

           Uri photoURI = Uri.fromFile(createImageFile());
          

           Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
          

        • 如果您使用意图让系统打开您的文件,您可能需要添加以下代码行:

        • If you're using an intent to make the system open your file, you may need to add the following line of code:

           intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
          

        • 请参考已经说明的完整代码和解决方案这里.

          Please refer to the full code and solution that have been explained here.

          这篇关于android.os.FileUriExposedException: file:///storage/emulated/0/test.txt 通过 Intent.getData() 暴露在应用程序之外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆