Flutter: Shared Storage (Storage Access Framework API) Permission for files inside hidden sub-directory not working
Finally I Found a package that can solve SAF issue ! Here is a link Visit
Comments
-
jvoltci over 1 year
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.
-
jvoltci about 2 yearsUsing Shared Storage API I have asked the user to give permission for the given directory thus consent to use this folder. Hope it clears your doubt!
-
blackapps about 2 yearsYou could have told that you used ACTION_OPEN_DOCUMENT_TREE to let the user choose a folder. Which folder to begin with?
-
blackapps about 2 yearsIt looks that you use a classic file path to that folder to make listings. That will not go as the obtained permission to read/write the folder and subfolders is only when using SAF to do so.
-
blackapps about 2 yearsAnd further we can nowhere in your post read what you try to achieve.
-
jvoltci about 2 years@blackapps can you elaborate this
That will not go as the obtained permission to read/write the folder and subfolders is only when using SAF to do so.
? Because I have access to files as well from adjacent subdirectory after SAF. -
jvoltci about 2 years@blackapps Edited the Problem statement a bit.
-
blackapps about 2 yearsYou did not tell which folder the user choosed.
-
jvoltci about 2 yearsI have mentioned it there. In this line
Permission Granted Directory: .../internal storage/Android/media
User has chosen this folder. '/storage/emulated/0/Android/media' -
blackapps about 2 yearsYou mentioned it too late. Instead of
a folder
you could have mentioned it. You mention a classic file system path. But in onActivityResult() you would get a content scheme uri for the chosen folder. Please tell how that content scheme looks like -
blackapps about 2 yearsOnce you got a content scheme for the chosen folder you should use that content scheme. It does not make sense to use a file system path like you do in
// path: '/storage/emulated/0/Android/media/neo/matrix/.new
-
jvoltci about 2 yearsAgain you missed
issue - Not able to list all files inside this Directory: .../internal storage/Android/media/neo/matrix/.new At the same time... Able to access files inside following dir: .../internal storage/Android/media/neo/matrix Also if I rename the folder ".new" to new I am able to list all the files inside that directory
It is working perfectly using the classic path with the Directory(path: "some/path") class from dart: io I request you to please go through the Problem statement completely. -
Ankit Parmar about 2 years@Jai I am facing the same problem unable to read Statues from hidden folder for this Path => /storage/emulated/0/Android/Media/com.whatsapp/WhatsApp/Media/.Statuses/ but when i Remove (.)dot from Statues folder I can read all the files from the Statues folder using this method. Directory dir = Directory( '/storage/emulated/0/Android/Media/com.whatsapp/WhatsApp/Media/Statuses/'); List<FileSystemEntity> allFiles = dir.listSync(); even without using SAF Api just took this permission from user Permission.storage.request() using permission_handler package
-