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

Gavin Wright
  • 3,124
  • 3
  • 14
  • 35
  • There are three calls in your code. It's unclear if you only complain about the first call. – blackapps Nov 18 '21 at 20:03
  • @blackapps 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. – Gavin Wright Nov 18 '21 at 21:03
  • 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. – blackapps Nov 18 '21 at 23:21
  • 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. – Gavin Wright Nov 19 '21 at 00:53
  • 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 file – tipa Jul 25 '22 at 11:04

1 Answers1

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.

blackapps
  • 8,011
  • 2
  • 11
  • 25
  • 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). – Gavin Wright Nov 21 '21 at 07:36
  • 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) – blackapps Nov 21 '21 at 08:06
  • `android:requestRawExternalStorageAccess="true` in application tag of manifest file. https://developer.android.com/reference/android/R.attr.html#requestRawExternalStorageAccess – blackapps Nov 21 '21 at 08:37
  • Enabling that makes no difference in terms of speed, unfortunately. But I appreciate the suggestion! – Gavin Wright Nov 21 '21 at 08:54
  • You only need path for [Os.statvfs](https://developer.android.com/reference/android/system/Os#statvfs(java.lang.String)). – Eugen Pechanec Nov 23 '21 at 20:42
  • 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. – Gavin Wright Nov 25 '21 at 08:07
  • @Eugen Pechanec I tried using `Os.statvfs` by passing it `rootUri.path` and it crashes with an ENOENT exception. – Gavin Wright Nov 25 '21 at 08:12