ContentResolver.openAssetFileDescriptor()在Android 12中需要很长时间

4
在Android 12中,该方法调用需要多秒才能返回:
``` val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r") ```
我传递了一个树形Uri,它代表一个USB驱动器的根目录。调用的执行时间取决于根目录所占用的空间大小。因此,对于1GB的空间,这个调用需要大约10秒钟。而在之前的Android版本中,这个调用只需要几毫秒就能返回。
我的目标是使用下面的代码来测量USB驱动器上的空间。是否有其他方法可以让这个过程在合理的时间内完成?
val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r")
val stats = Os.fstatvfs(descriptor!!.fileDescriptor)
val availableSpace = stats.f_bavail * stats.f_bsize

相关链接

Google问题跟踪器链接,包含示例项目


你的代码中有三个调用。不清楚你是否只是抱怨第一个调用。 - blackapps
@blackapps 问题出在 contentResolver.openAssetFileDescriptor() 这个调用上。我包含了其余的代码只是为了让你了解我试图实现什么。如果我测量这三行中的每一行,第一行需要多秒钟,而其他两行几乎是瞬间完成的。 - Gavin Wright
文件数量有影响吗?还是占用空间的大小?我发现,存储了大量文件的U盘需要更长时间才能挂载。 - blackapps
是的,看起来是这样。在我的运行Android 12的Pixel 6上,8GB的照片需要18秒,而8GB的大型视频只需要1.5秒。但在我运行Android 9的Pixel 2上,这些操作分别只需要30毫秒和8毫秒。 - Gavin Wright
我遇到了同样的问题。对我来说,当从OneDrive应用程序中选择一个尚未下载到设备上的大文件并尝试打开内容URL时,就会出现这种情况。我决定将该方法卸载到单独的任务中,以便在OneDrive下载文件时不会阻塞UI。 - tipa
1个回答

0

对于Android 12,您可以请求原始文件访问权限(忘记权限的正确名称)。

当您进行所有文件操作时,请通过MediaStore进行。

值得一试。


我认为你指的是MANAGE_EXTERNAL_STORAGE,它启用了“所有文件访问”权限。不幸的是,这似乎并没有解决问题。我仍然需要将Uri转换为ParcelFileDescriptor,而这个权限似乎并没有加速任何执行此操作的方法(这些方法都是ContentResolver的一部分)。 - Gavin Wright
在清单文件的应用程序标签中添加android:requestRawExternalStorageAccess="true"。参考链接:https://developer.android.com/reference/android/R.attr.html#requestRawExternalStorageAccess - blackapps
很遗憾,启用这个功能在速度方面没有任何区别。但是我感谢您的建议! - Gavin Wright
通常情况下,USB驱动器没有文件路径。我们只能使用Uri进行操作。据我所知,文件路径甚至不存在。 - Gavin Wright
@Eugen Pechanec 我尝试使用 Os.statvfs 并传递了 rootUri.path,但它会崩溃并抛出 ENOENT 异常。 - Gavin Wright
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接