Giter Site home page Giter Site logo

alexrintt / shared-storage Goto Github PK

View Code? Open in Web Editor NEW
52.0 4.0 21.0 1.27 MB

Flutter plugin to work with Android external storage.

Home Page: http://alexrintt.io/shared-storage/

License: MIT License

Kotlin 40.52% Dart 59.48%
plugin storage android dart flutter flutter-plugin acess framework saf

shared-storage's Introduction

#flutter, #package, #android, #saf, #storage

Shared Storage

Access Android Storage Access Framework, Media Store and Environment APIs through your Flutter Apps

Documentation

See the website for documentation.

All documentation is also available under /docs to each released version which is the data source of the website.

You can contribute to the documentation by just editing these files.

To check all ways you can contribute to this package see Contributing/Ways to contribute.

To start developing, use release branch as base, master is used for experimentation only and is likely to be not working.

All other branches are derivated from issues, new features or bug fixes.

Supporters

Contributors

shared-storage's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

shared-storage's Issues

Is it possible to recursively list the files in a subfolder?

Describe the bug

When I call the listFiles() method of a document, I get a list of files in that document's root(The one that was obtained via openDocumentTree()).

From the documentation, it doesn't seem like there is any way to get the list of files in a subfolder.

To Reproduce

Get a uri with openDocumentTree, then call listFiles on any subfolder.

The returned list will be that of the top-level document.

Expected behavior

The listing should be a list of files in the subfolder, or, if there is some other way to list a subfolder, this should be documented.

Relevant Links

It seems like there is or was some kind of bug in DocumentFile itself? Is it possible something else can override the build.gradle and pull in the buggy 1.0.0?

https://stackoverflow.com/questions/62375696/unexpected-behavior-when-documentfile-fromtreeuri-is-called-on-uri-of-subdirec

Here we have someone saying they still saw it on what they thought was 1.0.1 : https://issuetracker.google.com/issues/37081745

Further references to v1.0.1, and discussion of possible workarounds using singleUri: https://stackoverflow.com/questions/46180851/get-a-documentfile-that-is-a-child-of-a-document-tree-without-using-findfiles

Reference to using DocumentsContract to get around the weird URI behavior:

https://www.reddit.com/r/androiddev/comments/k1etf7/is_it_possible_to_recreate_a_documentfile_folder/?utm_medium=android_app&utm_source=share

And finally, in case someone as new as me to the whole Dart/Android thing takes on this, here is how one can list using a documents contract:
https://stackoverflow.com/questions/58201003/how-do-i-get-children-of-a-document-in-android-sorted-by-name

The issue seems to be, as far as I can tell, that fromTreeUri in Kotlin does not give a Document representing the Uri, it gives you the root, so doing the listing via a DocumentsContract should work. Perhaps I'll play around with this tomorrow.

Improve SDK versions handling

Current behavior

Current handling to unsupported SDK version is just throwing an result.notImplemented() which throws an MissingPluginImplementation.

Expected behavior

Improve the error and the SDK handling from the package side.

High-level features/use-cases research

Note
If you want to request some feature, you can include in the issue comments!

To see details, refer to #56.

The following features will be available on the next major release:

  • Pick a folder.
  • List files within a picked folder.
  • Deleted files within a picked folder.
  • Create a file within a picked folder.
  • Write to a file within a picked folder.
  • Read a file within a picked folder.

Outdated Kotlin Gradle plugin version

Describe the bug
When building the app for android, this error comes up:

FAILURE: Build failed with an exception.

* What went wrong:
The Android Gradle plugin supports only Kotlin Gradle plugin version 1.5.20 and higher.
The following dependencies do not satisfy the required version:
project ':shared_storage' -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50

To Reproduce

  1. Upgrade Android Gradle Plugin to 7.3.0.
  2. Run flutter build apk

Expected behavior
The app should build successfully, without any error.

Deeply Search About SAF `BroadcastReceivers`

What is this API about?

Is about to search about the support for BroadcastReceiver API's which allow us to listen to storage permissions changes

What will be possible?

  • Listen when a folder is removed from allowed folders
  • Listen when a folder is removed from original location

Some Useful Links

Add some way to update/overwrite file contents (e.g `updateFile(...)`)

Feature request

Currently we can't overwrite/update the content of a given file we already have permissions over.

So the request is only to add an API which purpose is to receive a given uri and content or bytes as parameters and overwrite the content.

Sample usage:

final updatedFile = await updateFile(
  targetFile,
  bytes: UintList.fromList('content in bytes'.codeUnits),
  content: '...',
);

This will permit edit only the file contents and not the file mime type.

Useful resources

Originally requested by @jfaltis at #61.

When i try to getRealPathFromUri(directory_name), it shows me below error

When i try to getRealPathFromUri(directory_name), it shows me below error

E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): Failed to handle method call
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FDemo
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:174)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.content.ContentProviderProxy.query(ContentProviderNative.java:472)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.content.ContentResolver.query(ContentResolver.java:1183)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.content.ContentResolver.query(ContentResolver.java:1115)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.content.ContentResolver.query(ContentResolver.java:1071)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileHelperApi.getDataColumn(DocumentFileHelperApi.kt:205)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileHelperApi.getPath(DocumentFileHelperApi.kt:177)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileHelperApi.getRealPathFromUri(DocumentFileHelperApi.kt:64)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileHelperApi.onMethodCall(DocumentFileHelperApi.kt:56)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:320)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.os.Looper.loop(Looper.java:223)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at android.app.ActivityThread.main(ActivityThread.java:7656)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfilehelper( 5134): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/flutter ( 5134): Exception while create new file: PlatformException(error, Unsupported Uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FDemo, null, java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/primary%3ADownload%2FDemo

Originally posted by @manojSimfrom in #20 (comment)

filename is in correct when we create multiple instance of same file?[Android 9]

Describe the bug
The filenames are wrong when we save the same file multiple times in Android 9 version phones.

To Reproduce

  1. Grant document tree permission to any directory.
  2. Save the file using createFileAsString method in the storage
  3. save the Same file multiple times. like "myfile.csv"

Expected behavior
When we save the same file multiple times it should create the files as below
First time - myfile.csv
Second time - myfile (1).csv
Thrid time - myfile (2).csv

Note: It's working fine in Android 10 and above versions, But I have check-in 2 phones(Vivo and Asus) with android 9 and in those phones, it generates the above files as below which is a totally incorrect file format.

First time - myfile.csv
Second time - myfile.csv (1)
Thrid time - myfile.csv (2)

Screenshots
Screenshot_20220413-142511

Add API to allow read data from a specific `URI`

Details

The most recent Android API's, handle the files as a database of URI's, so we can handle it by adding support for cursor queries, as required by #10, thanks @ankitparmar007.

Tasks

  • Search and add experimental APIs to allow this usecase.
  • Add support for initialUri.
  • Add copy API to allow export files.
  • Get data dir from a specific app (package id) (Not covered by this package).

Issues

Useful resources

Can't call multiple 'listFiles' at once

Wanted to get count of files of each persisted folder that means I want to call 'listFiles' multiple times depending on persisted folders count. But I get only last folder item count if not "awaiting" for each function call in loop.

q.mp4

Quick demo, where I perfom 'listFiles' with "await" and not

Looks like that function acts not like it intended as I can't see any notes that I can't perform it multiple times at the same time.

Also… maybe there are more efficient way to get persisted folders items count than use of 'listFiles'?

Required Tiny patches/updates for `v0.2.0`

Tasks

Tasks required to release the v0.2.0 version

  • Add script to auto-publish the package when a new commit is pushed to the release branch
  • Finish all TODO's
  • Update documentation README.md
  • Update CHANGELOG.md

No feedback when the user doesn't select a folder

I'm trying to show the user an alert when they haven't selected a folder to let them know their file won't be downloaded, but in the case that no URI is returned from the document tree in openDocumentTree, nothing is sent back to flutter.

I don't know whether it makes sense to do something like pendingResult.second.success(null) (or even pass the uri regardless of whether it is null) or to return an error case that would need to be handled in flutter, such as an error saying that no folder was chosen.

If you have a preference I'm happy to open a PR against this.

I'm trying to make use of the latest version from master at the moment as I needed access to some of the code as-yet unreleased on pub.dev.

Thanks!

Unused arguments in `DocumentFile.getContent`

Describe the bug
Both DocumentFile.getContent and DocumentFile.getContentAsString demand a parameter called Uri destination.
It is unclear to me why this parameter is needed and it is entirely unused in the code.

Expected behavior
I would assume that neither of those functions would take a parameter, as their location is already available in the properties of the DocumentFile itself.

shared_storage:

  • Version 0.5.0

Subfolder content listing not working

Describe the bug

Subfolder listing not working even with #59 and #58 when we try to open a subfolder a permission error is thrown even with storage permission access over the parent uri.

To Reproduce

Open the example app in the master/release branch at the latest commit of the current timestamp and try to open a subfolder of a granted uri, it will show a "No permission" error, even though not necessary to request the folder permission again for each subfolder.

Expected behavior

List all subfolders and subfolder contents without the need of requesting the permission over the Uris twice.

Screenshots

Not applicable.

Additional context

The solution can be "picked up" from android/storage-samples on the ActionOpenDocumentTree demo.

What if persisted document directory get deleted by the user?

Describe the bug
In my App, I have selected one directory to store files and then I deleted that directory manually so next time I'll get the URL when I call persistedUriPermissions but when I try to add files under that directory it throws the error as directory does not exists which is correct. So What is the solution/workaround for this using which we can identify whether the persisted URL path exists or not?

Even I am not able to find the real path from the Document Tree URL.

To Reproduce

  1. OpenDocument Tree
  2. Save the file on the above path using createDocumentFile.
  3. Delete the Directory to which we gave access in step 1 manually.
  4. Next time when we try to store a file we will check any URL available or not in persistedUriPermissions and we will find that url in the list.
  5. When we try to store the file using the persistedUriPermissions item it will throw an error as Directory does not exist.

Expected behavior
I want a solution/workaround using either We can check the persisted Uri exists or not or I want real path using which I can manually check the directory exists or not.

Add support for apk (request install intent)

Implement intent in the openDocumentFile API to handle apk install request, requires install package permission:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

openDocumentFile() returns null

Describe the bug
documentFile.openDocumentFile returns null, even on success

To Reproduce
final result = await documentFile.openDocumentFile()

Expected behavior
result to be true on success

Smartphone (please complete the following information):

  • Device: android emulator
  • OS: android api 33
  • Version 0.7.1

Additional context
this problem is reproducable using the sample app: example/lib/utils/document_file_utils.dart:25
launched is null on successful launch

ReadPermission False

Read Permission is false even after openDocumentTree
but write permission is true

No Read Permission on PersistedUris

final selectedUriDir = await openDocumentTree();

selectedUriDir = content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses

final listOfPersistedUris = await persistedUriPermissions();

listOfPersistedUris [UriPermission(isReadPermission: false, isWritePermission: true, persistedTime: 1638318739830, uri: content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses)]

AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

**

  • compileSdkVersion 31
  • minSdkVersion 24
  • targetSdkVersion 31

**

Cannot creat DocumentFile from uri returned by getMediaStoreContentDirectory

Describe the bug
I try to create an instance of DocumentFile from URI returned by getMediaStoreContentDirectory() function.
Unfortinately when I call .toDocumentFile() on the URI I get an exception:

E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): Failed to handle method call
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): java.lang.IllegalArgumentException: Invalid URI: /external/downloads
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.provider.DocumentsContract.getDocumentId(DocumentsContract.java:1278)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.lakscastro.sharedstorage.storageaccessframework.lib.DocumentCommonKt.createDocumentFileMap(DocumentCommon.kt:48)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileApi.onMethodCall(DocumentFileApi.kt:94)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Looper.loopOnce(Looper.java:201)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Looper.loop(Looper.java:288)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.app.ActivityThread.main(ActivityThread.java:7839)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

To Reproduce
Lets take Downloads folder for example. The same issue happens when you use other media store directories as well.
Try to create DocumentFile from Downloads directory URI returned by getMediaStoreContentDirectory call like this.

(await getMediaStoreContentDirectory(MediaStoreCollection.downloads))!.toDocumentFile();

Observe the exception

E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): Failed to handle method call
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): java.lang.IllegalArgumentException: Invalid URI: /external/downloads
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.provider.DocumentsContract.getDocumentId(DocumentsContract.java:1278)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.lakscastro.sharedstorage.storageaccessframework.lib.DocumentCommonKt.createDocumentFileMap(DocumentCommon.kt:48)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.lakscastro.sharedstorage.storageaccessframework.DocumentFileApi.onMethodCall(DocumentFileApi.kt:94)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:319)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Looper.loopOnce(Looper.java:201)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.os.Looper.loop(Looper.java:288)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at android.app.ActivityThread.main(ActivityThread.java:7839)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/MethodChannel#io.lakscastro.plugins/sharedstorage/documentfile(13713): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Expected behavior
DocumentFile instance is created from the given URI

Write to a file

How would you use this plugin to write to a file in a folder which access was granted through SAF?

I tried to use the File class and writeAsString from dart:io but I was not able to obtain a proper path through the Uri with toFilePath().

final Uri uri = widget.partialFile.metadata!.uri!;
final file = File(uri.toFilePath());

causes

E/flutter (18993): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Unsupported operation: Cannot extract a file path from a content URI
E/flutter (18993): #0      _Uri.toFilePath (dart:core/uri.dart:2825:7)
E/flutter (18993): #1      _FolderFileCardState.build.<anonymous closure> (package:shared_storage_example/screens/folder_files/folder_file_card.dart:182:39)
E/flutter (18993): #2      _FolderFileCardState.build.<anonymous closure> (package:shared_storage_example/screens/folder_files/folder_file_card.dart:180:22)
E/flutter (18993): #3      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:1005:21)
E/flutter (18993): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:198:24)
E/flutter (18993): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:613:11)
E/flutter (18993): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:298:5)
E/flutter (18993): #7      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:269:7)
E/flutter (18993): #8      GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
E/flutter (18993): #9      GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:449:20)
E/flutter (18993): #10     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:425:22)
E/flutter (18993): #11     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:329:11)
E/flutter (18993): #12     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:380:7)
E/flutter (18993): #13     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:344:5)
E/flutter (18993): #14     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:302:7)
E/flutter (18993): #15     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:285:7)
E/flutter (18993): #16     _rootRunUnary (dart:async/zone.dart:1442:13)
E/flutter (18993): #17     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (18993): #18     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (18993): #19     _invoke1 (dart:ui/hooks.dart:170:10)
E/flutter (18993): #20     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:331:7)
E/flutter (18993): #21     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)

And once while testing toFilePath() did not cause an error. Opening the file did however.

E/flutter (18993): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: FileSystemException: Cannot open file, path = '/tree/primary%3ADocuments/document/primary%3ADocuments%2FSample%20File.txt' (OS Error: No such file or directory, errno = 2)
E/flutter (18993): #0      _File.open.<anonymous closure> (dart:io/file_impl.dart:356:9)
E/flutter (18993): #1      _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter (18993): #2      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (18993): <asynchronous suspension>
E/flutter (18993): 

It would be great to extend the plugin example with this functionality.

This plugin is API based instead of functionality based

Note
Issue created in favor of the Flutter docs and their recommended post by Mehmet Fidanboylu.

The issue is in the core of this plugin:

In 2021 I created this plugin just to allow access to one, two methods available on Android APIs, so I thought that's was fine to create a plugin fully-based on native APIs. But since the package grown and people wanted to add support to another features I noticed two issue:

  • It's impossible to a plugin follow all Android APIs maintained only by one developer.
  • Kotlin != Dart and Flutter != Android. That is:

APIs don’t match across platforms and you are forced to expose an intersection of the API often with crippling consequences…
- Mehmet Fidanboylu.

  • Missing tests. This one is probably the critical one.

So the following actions will be taken to the next major release:

  • Deprecate all mirror APIs.
  • Keep/add feature-based APIs.
  • Add support for iOS.

Requirements/Recommended technical fixes:

That's it, this issue is just a wrapper issue to provide some context to create another minor and more specific issues.


That's all folks!

Do I need to configure anything in AndroidManifest.xml?

I want to use the openDocumentTree method to authorize the Android/data/somedirectory/ Directory
Then use the getDocumentContent method to read or write sub files in the directory, so I don't need to authorize the files I want to read and write again through the openDocument method.

Because my current situation is that if I edit the file using another app (an app of the file management editing type), the sub file permissions that I authorize using the openDocument method within my application will become invalid, and then I need to call the openDocument method again to let the user select the file to regain read and write permissions.

So I want to make sure that my application won't invalidate my file permissions when other applications edit the file. Do I need to configure something in AndroidManifest.xml? How can I achieve this

Losing access to folder contents after device reboot

Hi!

My case is in-app music player. User opens some directories (openDocumentTree) and watch music content in the app UI.

All works fine till device reboot. After reboot I see list of persisted folders (persistedUriPermissions) but when I trying to access contents of folder I get "No permission granted" error. Ask user for granting permissions each time is not user friendly and I looking for solution on this issue.

Watched your example app but seen same problem there: list of persisted uris and no permission on reading contents each device reboot.

shared_storage_question.mp4

Quick demo of problem.

After some research I found that we need strictly specify that we need grant access across device reboots . As I can see your openDocumentTree function has parameter 'persistablePermission' that looks like granting permissions across reboots is default behaviour but seems not work.

So… what can I do for granting folder contents read permissions device across reboots?

`getDocumentContent` takes too long to return when file is too large

Describe the bug

getDocumentContent function "crash" the app if the document is too long.

This happens when trying to read apk files.

To Reproduce

Open the example app and try to click over an apk file card.

Expected behavior

There's some way to asynchronously read the file contents.

Screenshots

Not applicable.

Additional context

Possible solutions:

  • Maybe we can refactor the current function to return a Stream that emits a new event right after each new line rather of reading all lines then returning.
  • Do the same above but for a new function.

Intent `ACTION_VIEW` not working properly

Describe the bug

When trying to open a document file through openDocumentFile API which uses ACTION_VIEW under the hood, the prompt is showing up but no data is sent to the third party application, which results in a incosistent behavior: the file is shown as a corrupted file (since the data is not being sent).

To Reproduce

Go to the example folder at the latest master commit at this time, open a folder and click on Open with option over any document.

Expected behavior

The document file should be shown properly, if it's an image it's should be displayed, if it's a video should be played and so on...

Screenshots

Not applicable.

Additional context

Solution is available here at android/storage-samples.

Plugin example seems to be broken in v0.4.0

The plugin example seems to be broken in v0.4.0

[jona@jona example]$ flutter run
Running "flutter pub get" in example...                          1.123ms
Launching lib/main.dart on  in debug mode...
Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://schemas.android.com/repository/android/common/01
Warning: Mapping new ns http://schemas.android.com/repository/android/generic/02 to old ns http://schemas.android.com/repository/android/generic/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/02 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/03 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/02 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/03 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/03 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: unexpected element (uri:"", local:"base-extension"). Expected elements are <{}codename>,<{}layoutlib>,<{}api-level>
lib/main.dart:2:8: Error: Error when reading 'lib/screens/persisted_uris/persisted_uri_list.dart': No such file or directory
import 'screens/persisted_uris/persisted_uri_list.dart';
       ^
lib/main.dart:17:36: Error: Method not found: 'PersistedUriList'.
    return const MaterialApp(home: PersistedUriList());
                                   ^^^^^^^^^^^^^^^^


FAILURE: Build failed with an exception.

* Where:
Script '/opt/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 1156

* What went wrong:
Execution failed for task ':app:compileFlutterBuildDebug'.
> Process 'command '/opt/flutter/bin/flutter'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 11s
Running Gradle task 'assembleDebug'...                             11,7s
Exception: Gradle task assembleDebug failed with exit code 1

Originally posted by @jfaltis in #61 (comment)

Cannot get full access to SD Card

Could not get full access to SD card
I'm working on a file manager using flutter. Because of limitations of writing access to external storage is denied and new android versions are making it too hard to get access to folders like Android/data, Android/obb and sdcard/Android/, I tried Storage Access Framework (SAF). But, I see that even this package could not get full access to SD card because of privacy related issues.
It is very easy to reproduce this error

  1. Using SAF, try to get an access to sdcard in Android 12. There you will see that access to sd card is locked.

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
Screen Shot 2022-12-22 at 20 04 16

Android Phone

  • Any Android phone
  • Above 12

Add request for file writing

A Feature request

I need to usa the setPosition methd to modify some file. But after I refer your API document, I can't find any thing about this. So I give some suggestion here. If writeToFileAsBytes supports setPosition, it will be better.

List files in a chosen uri

Thanks for the awesome package great work.

1- I have some data saved like pics, audios and pdfs, I need to list and read all the files in a chosen URI.
2- How to create a directory, I want to know mime type for the directory?

Thanks. @lakscastro

Use of listFiles() without the ID column results in a null pointer casting crash.

Describe the bug
Specifically, we get an error trying to cast a null to a Kotlin String on that appears to be from line 212(https://github.com/lakscastro/shared-storage/blob/1bfeb88df69938c62d7709861cc426ec71515f3c/android/src/main/kotlin/io/lakscastro/sharedstorage/storageaccessframework/lib/DocumentCommon.kt), if one tries to iterate anything without enabling the id column.

val id =
          data[DocumentsContract.Document.COLUMN_DOCUMENT_ID] as String

Seems to be the culprit line.

I'm not actually sure this is really a bug, it might be simpler just to document that the Id column is needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.