加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Android中的FileUriExposedException

发布时间:2020-12-14 05:52:36 所属栏目:Java 来源:网络整理
导读:我需要在包含图像的内部存储中打开文件夹. 我使用以下代码. Java的 File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyPhotos");Intent intent = new Intent(Intent.ACTION_VIEW);String path =fol
我需要在包含图像的内部存储中打开文件夹.

我使用以下代码.

Java的

File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"MyPhotos");
Intent intent = new Intent(Intent.ACTION_VIEW);
String path =folder.getPath();
Uri myImagesdir = Uri.parse("file://" + path );
intent.setDataAndType(myImagesdir,"*/*");   
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

PATHS

<paths xmlns:android="http://schemas.android.com/apk/res/android">
     <external-path name="images" path="Pictures" />
     <external-path name="external_files" path="."/>
     <external-path name="files_root" path="Android/data/${applicationId}"/> </paths>

表现

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.android.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

XML / file_paths

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="images" path="Pictures" />
    <external-path name="external_files" path="."/>
    <external-path name="files_root" path="Android/data/${applicationId}"/>
</paths>

错误

FATAL EXCEPTION: main Process: android.apps.bnb.company.myphotos,PID:
22482
android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/MyPhotos exposed beyond app
through Intent.getData()

是否有其他方法可以在内部存储中打开文件夹?谢谢!

更新#1

使用这个arcticle https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en我替换了

Uri myImagesdir = Uri.parse("file://" + path );

Uri myImagesdir = Uri.parse("content://" + path );

并且错误消失了.

无论如何,我必须选择始终应用程序来打开此文件夹.

默认情况下是否可以使用“我的文件”应用程序打开某个文件夹?

解决方法

Is it possibility to use My Files app by default to open certain folder?

是的&不.它不是100%保证它可以在所有设备上运行.

编辑1:

以下是可以完成的方法之一.我已经测试了几个模拟器(运行Android N& Android O)并加载默认文件资源管理器:

MainActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri dirUri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName() + ".com.example.myapplication",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        //intent.setDataAndtType(); I will change this value in the alternatives below
    }

AndroidManifest.xml中

<provider
        android:name=".GenericFileProvider"
        android:authorities="${applicationId}.com.example.myapplication"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

GenericFileProvider.java

public class GenericFileProvider extends FileProvider {
}

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

上述方法不适用于像三星这样的大玩家

备择方案

1.使用DocumentsContract.Document.MIME_TYPE_DIR类型

intent.setDataAndType(dirUri,DocumentsContract.Document.MIME_TYPE_DIR);

此方法适用于多个仿真器和有限的设备集.它不适用于像三星或华为这样的大公司.

2.使用类型资源/文件夹

intent.setDataAndType(dirUri,“资源/文件夹”);

仅当用户安装了ES文件资源管理器应用程序时,此方法才有效.

如果您选择使用,那么您必须使用以下方法检查是否有任何意图可以处理它:

PackageManager packageManager = getActivity().getPackageManager();

if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent);
} else {
   // either display error or take necessary action
}

3.使用类型* / *

intent.setDataAndType(dirUri,“* / *”);

如果用户从Intent Chooser中选择文件管理器应用程序并将其标记为处理* / *的默认应用程序,则此方法有效.但它有一些缺点(感谢@CommonsWare带来的一些):

>此类型将加载设备上的所有应用程序,并允许用户选择其中一个来完成操作.
>如果没有文件资源管理器并且用户选择其他应用程序来加载您的意图,那么另一个应用程序将崩溃或只是显示黑屏.例如.您使用Gallery或其他应用程序启动它而不是文件资源管理器,然后Gallery应用程序将崩溃或显示黑屏.
>即使有文件浏览器,但用户决定使用其他应用程序,其他应用程序可能会崩溃

4.使用text / csv类型

intent.setDataAndType(uri,“text / csv”)

这将限制将向用户显示的应用程序数量,但在应用* / *时会限制相同的限制.将显示可以处理csv的应用程序,如果用户选择它,则应用程序将崩溃.

正如@Academy of Programmer所提到的,有一些特定于设备的实现可用于here,它需要通过它来识别默认文件管理器的意图和额外需求.

结论:

没有标准类型可用于实现它,因为目前没有标准文件管理器支持特定类型.将来谷歌可能会拿出一些方法.最好的替代方案是像Dropbox或Google Drive一样实现自己的文件管理器.有几个库提供此功能.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读