随着谷歌存储策略的更新,我不得不改变保存文件的方式。
首先,我的应用程序以前将项目文件夹保存到/sdcard/。然而,由于这个策略,使用File的访问变得不可能了,我尝试了几种方法。
我还考虑将其保存在应用程序特定的文件空间中,但由于删除应用程序时不应该删除项目文件夹,所以不能使用该文件夹。
1.使用MediaStore
一开始,我尝试使用MediaStore。我可以使用RELATIVE_PATH将文件放到文件夹中,但是文件的控制非常困难,项目文件夹中的文件也是与媒体无关的文件(照片、视频、音乐)。
2.使用DocumentFile
我找到了另一条路。使用意图的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!
}
}发布于 2020-11-15 09:39:47
对于Android 10,您可以在清单中请求遗留的外部存储,并且可以继续使用File类等旧方式。
对于Android 11,可以使用您自己的目录,比如下载、文档、图片、警报等等。也不需要苏丹武装部队。
发布于 2022-01-24 22:36:12
SAF确实是慢的,当findFile()算法没有优化时,它甚至更慢。根据我的基准的扩展函数DocumentFile.child()从SimpleStorage,它可以执行36%的速度。
要使用此函数,只需将findFile()替换为child()
// Before
val file = folder.findFile("Movies")?.findFile("Infinity War.mp4")
// After
val file = folder.child("Movies/Infinity War.mp4")https://stackoverflow.com/questions/64842185
复制相似问题