androidflutterkotlindarthidden

Flutter: Shared Storage (Storage Access Framework API) Permission for files inside hidden sub-directory not working


How to achieve to listing all files (e.g. Media) inside hidden subdirectory i.e. folder name start with '.' e.g. "(.media)" after using SAF in Flutter/Dart?

I have used ACTION_OPEN_DOCUMENT_TREE to let the user choose a folder [So to avoid using MANAGE_EXTERNAL_STORAGE] but couldn't view i.e. Read the files inside the hidden subdirectory of the folder.

Permission Granted folder is media:

storage/emulated/0/internal storage/Android/media/matrix/.new/

Issue:

Not able to list all files inside subfolder .new

At the same time...

Able to access files (not folder) inside matrix subfolder

Also if I rename the subfolder ".new" to new I am able to list all the files inside that folder

I am using flutter/dart. For Shared Storage Permission, I have used Kotlin custom native code.

Kotlin Code:

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {

        GeneratedPluginRegistrant.registerWith(flutterEngine)

        MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)

                .setMethodCallHandler{ call: MethodCall, result: MethodChannel.Result -> run {
                                if (call.method.contentEquals("getSAFPermission")) {
                                    if (VERSION.SDK_INT > 29) {
                                        openDirectory(_initialPickerDirPath) //@String path
                                    } else {
                                        result.success(true)
                                    }
                                }
                            }
                        }
}

private fun openDirectory(pickerInitialUri: String) { 
           val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
            putExtra(DocumentsContract.EXTRA_INITIAL_URI,DocumentsContract.buildDocumentUri(
                "com.android.externalstorage.documents", pickerInitialUri)
                }

            startActivityForResult(intent, SAF_PERMISSION_CODE)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
          if (requestCode == SAF_PERMISSION_CODE && resultCode == Activity.RESULT_OK) {

             val contentResolver = applicationContext.contentResolver

             val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION or 
                                   Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

             contentResolver.takePersistableUriPermission(treeUri, takeFlags)
          }
}

Flutter side | Dart Code:

_loadimage() async {
    // path: '/storage/emulated/0/Android/media/neo/matrix/.new'
    if (Directory(_neoDir.path).existsSync()) { // _neoDir: Directory
      imageList += _neodDir
          .listSync()
          .map((item) => item.path)
          .where((item) => item.endsWith(".jpg"))
          .toList(growable: false); // imageList appear empty list
    }
}

Tried method:

1. In the native Kotlin side, fetched child document files using CachingDocumentFile and iterating over all DocumentFile and storing Uri list in string and sending it back to Flutter side. Rendering image File.fromUri() at dart side (Flutter)

Refer - > https://github.com/android/storage-samples/tree/main/ActionOpenDocumentTree

2. Used the solution of these folks. Refer > https://github.com/lakscastro/shared-storage/issues/10#issuecomment-1025801272

I feel I am not getting the read permission for child document files.

Note:- As of 31-Jan-2022 No flutter package helps to achieve this functionality. Tried given packages :

shared_storage, > https://pub.dev/packages/shared_storage

file_picker, > https://pub.dev/packages/file_picker

filesystem_picker, > https://pub.dev/packages/filesystem_picker

FileManager (discontinued class)

Any help would be greatly appreciated.


Solution

  • Finally I Found a package that can solve SAF issue ! Here is a link Visit