2

随着谷歌存储策略的更新,我不得不改变我保存文件的方式。

首先,我的应用程序之前将项目文件夹保存到 /sdcard/。但是,由于这个政策,使用 File 访问变得不可能,我尝试了几种方法。

我也想过把它保存在一个特定于应用程序的文件空间中,但是由于删除应用程序时不应删除项目文件夹,因此无法使用。

1.使用媒体存储

起初,我尝试使用 MediaStore。我可以使用RELATIVE_PATH将文件放在一个文件夹中,但是文件的控制非常困难,并且项目文件夹中的文件也是与媒体(照片,视频,音乐)无关的文件。

2.使用文档文件

我找到了另一种方法。使用 Intent 的 ACTION_OPEN_DOCUMENT_TREE,我从用户那里获得了项目文件夹的访问权限和树 uri,并且我能够通过使用它创建 DocumentFile 来访问该文件。

起初我认为这是一个非常好的方法,但很快我发现它很慢。

特别是对于 findFile() 方法,扫描单个文件需要将近一秒钟的时间。我的项目文件夹里有几十个文件,所以这个不能商业化。

有没有更好的办法?有一些帖子要求您试用 DocumentContracts,但似乎没有获取文件列表或检查它们是否存在的功能。

以下是我当前的代码:首先,请求树 uri:

public void getTreeUri(View view) {
    Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(i, 200);
}

二、获取树uri:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode==200 && resultCode == Activity.RESULT_OK) {
        final int takeFlags = data.getFlags()  & (Intent.FLAG_GRANT_READ_URI_PERMISSION  | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        getContentResolver().takePersistableUriPermission(data.getData(), takeFlags);

        Log.d("test", "Tree Uri: " + data.getDataString());

        treeUri = data.getDataString();
        getFileList();
    }
}

而且,尤其是这样使用 findFile 时,它​​会变得非常慢。

public void getFileList(){
    DocumentFile df = DocumentFile.fromTreeUri(this, Uri.parse(treeUri));
    DocumentFile[] df_list = df.listFiles();
    for (DocumentFile each : df_list){
        Log.d("test","File: "+ df.findFile(each.getName()));  //findFile method is too SLOW!
    }
}
4

2 回答 2

0

对于 Android 10,您可以在清单中请求旧版外部存储,并且可以使用 File 类等以旧方式继续。

对于 Android 11,请在下载、文档、图片、警报等公共目录之一中使用您自己的目录。也不需要 saf。

于 2020-11-15T09:39:47.550 回答
0

SAF 确实很慢,在findFile()算法没有优化的情况下更慢。根据我使用SimpleStorage扩展功能DocumentFile.child()的基准测试,它的执行速度可以提高 36%。

要使用此功能,只需替换findFile()child()

// Before
val file = folder.findFile("Movies")?.findFile("Infinity War.mp4")

// After
val file = folder.child("Movies/Infinity War.mp4")
于 2022-01-24T22:36:12.307 回答