ContentResolver.openAssetFileDescriptor() takes a long time in Android 12
Asked Answered
C

1

4

In Android 12, this method call takes multiple seconds to return:

val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r")

I'm passing it a tree Uri which represents the root of a USB drive. The call takes longer depending on how much space is taken up on the root. So for 1GB, it takes about 10 seconds. This isn't the case in previous Android versions, where the call returns in just a few millis.

My goal is to measure the space on a USB drive using the code below. Is there something else I can do to make this complete in a reasonable amount of time?

val descriptor = contentResolver.openAssetFileDescriptor(rootUri, "r")
val stats = Os.fstatvfs(descriptor!!.fileDescriptor)
val availableSpace = stats.f_bavail * stats.f_bsize

Relevant link

Google Issue tracker link with sample project

Crucify answered 18/11, 2021 at 10:40 Comment(5)
There are three calls in your code. It's unclear if you only complain about the first call.Thayer
@Thayer The problem is with the contentResolver.openAssetFileDescriptor() call. I included the rest of the code just to give context for what I'm trying to achieve. If I measure each of those three lines, the first takes multiple seconds while the other two are almost instantaneous.Crucify
Does amount of files have influence? Or amount of space occupied? I found that pendrives with a lot of files on them took longer to mount.Thayer
Yes, that seems to be the case. On my Pixel 6 running Android 12, 8 GB of pictures took 18 seconds, while 8 GB of large videos took 1.5 seconds. But on my Pixel 2 running Android 9, these operations took only 30 ms and 8 ms, respectively.Crucify
I am seeing the same issue. For me this happens when picking a large file form the OneDrive app (which has not been downloaded to the device yet) and trying to open the content URL. I decided to offload the method in a separate task to not block the UI while OneDrive is downloading the fileEastbourne
T
0

For Android 12 you can request raw file acces. (Forgot the right name of the permission)

When you do all file operations pass by the mediastore.

Worth a try.

Thayer answered 21/11, 2021 at 6:41 Comment(7)
I think you're referring to MANAGE_EXTERNAL_STORAGE, which enables "All files access". Unfortunately, this seems to not solve the problem. I still need to turn a Uri into a ParcelFileDescriptor, and this permission doesn't seem to speed up any of the methods for doing that (these methods are all part of ContentResolver anyways).Crucify
That was 'all files access'. No i do not refer to that. There is one with RAW in it. (Sorry, i'm laying under a palm tree right now ;-) no code at hand)Thayer
android:requestRawExternalStorageAccess="true in application tag of manifest file. developer.android.com/reference/android/…Thayer
Enabling that makes no difference in terms of speed, unfortunately. But I appreciate the suggestion!Crucify
You only need path for Os.statvfs.Divebomb
There usually isn't a filepath for USB drives. We only have the Uri to work with. As far as I know, the filepath doesn't even exist.Crucify
@Eugen Pechanec I tried using Os.statvfs by passing it rootUri.path and it crashes with an ENOENT exception.Crucify

© 2022 - 2024 — McMap. All rights reserved.