Search code examples
androidandroid-filefilefilter

Android 11 (30 API) File.listFiles() doesn't return all files


So I tested 29 and 30 Android API devices. Both has Download folder with 5 files (equal for both devices).

App has <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> in manifest and requests it in runtime.

Also includes android:requestLegacyExternalStorage="true" (which is only for Android 10, Android 11 ignores it)

private fun init() {
    val path = File(Environment.getExternalStorageDirectory(), "Download")
    val files = path.listFiles()
    Timber.d("Android API ${Build.VERSION.SDK_INT}, dirFiles \n${files?.joinToString(separator = "\n") { it.name }}")
}

Android 11 (30 SDK):

2021-10-06 23:40:52.182 9022-9022/com.example.tests D/MainActivity: Android API 30, dirFiles 
    Elephants Dream.srt
    Elephants Dream.mkv

Android 10 (29 SDK):

2021-10-06 23:45:51.835 8293-8293/com.example.tests D/MainActivity: Android API 29, dirFiles 
    Elephants Dream.srt
    Elephants Dream.ssa
    Elephants Dream.vtt
    Elephants Dream.ass
    Elephants Dream.mkv

As you can see Android 11 doesn't return all files using File.listFiles() method.

It filters files on system level by some Media filter. p.s. MediaStore cursor query returns same limited results

It recognizes that srt format subtitles file is media type, but ssa, vtt or ass subtitles file aren't media!

Quite weird logic. ssa, vtt, ass are also subtitles!

For Android 10 READ or WRITE storage permissions looks like this in the settings:

enter image description here

For Android 11 READ or WRITE storage looks like this:

enter image description here

I have an video player app which has to support many subtitles formats but I can only get srt on Android 11.

How to get all needed files?

UPDATE

Seems the only way for Android 11 is Request All files access https://developer.android.com/training/data-storage/manage-all-files#all-files-access

But it will be challenging to be approved by Google

We could use SAF (Storage Access Framework) but it has many limitations for Android 11 https://developer.android.com/training/data-storage/shared/documents-files#document-tree-access-restrictions

enter image description here


Solution

  • VLC media player uses android.permission.MANAGE_EXTERNAL_STORAGE (All files access) permission now https://github.com/videolan/vlc-android/blob/89c2deb5fd4983dd64e0e55bc5ab8e559612c9d9/application/vlc-android/AndroidManifest.xml#L12

    So this is the only way to access all types/formats of subtitles and videos but the only problem if Google will allow and approve such permission for your app.

    Usually this permission can be used without any problems in such apps like file browsers, antivirus scan and so on, but official docs say nothing about media players.

    There are new Media permissions (for video, audio, image) but they are useless, video media permission doesn't see all available video formats, only general ones, and there is no subtitle permission so the app could access srt, ass, vtt and other formats of subtitles.

    So VLC app update with all file access permission was approved by Google but my video player app was rejected as I said before in the comments. Both VLC and my app use libVLC to play different format of videos and subtitles but permission can be used by not each app of the same category...

    https://developer.android.com/training/data-storage/manage-all-files

    enter image description here