Android Sd Card Write Permission Using Saf (Storage Access Framework)

Android SD Card Write Permission using SAF (Storage Access Framework)

Letting the user choose the "SD card" or even the "Internal storage" SAF root give your application access to the corresponding storage, but only through the SAF API, not directly via the filesystem. For example you code could be translated into something like :

public void writeFile(DocumentFile pickedDir) {
try {
DocumentFile file = pickedDir.createFile("image/jpeg", "try2.jpg");
OutputStream out = getContentResolver().openOutputStream(file.getUri());
try {

// write the image content

} finally {
out.close();
}

} catch (IOException e) {
throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
}
}

In recent version of Android, accessing data outside your application using java.io.File is almost completely deprecated.

Does SAF(Storage Access Framework) solve the SD card WRITE issue in Android 4.4 (KitKat)?

When implementing a DocumentsProvider, you can only extend access to files on disk that you already have access to. Adding a DocumentsProvider doesn't give you any new access, so you probably don't need to implement one.

You can gain write access anywhere on an SD card by using the ACTION_OPEN_DOCUMENT or ACTION_CREATE_DOCUMENT intents that you mentioned. There is an ExternalStorageProvider built into the system that has access to all SD cards, and it will gladly delegate write access to you once confirmed by the user through those intents.

Users may need to enable "Settings > Display advanced devices" to show the SD cards offered by ExternalStorageProvider. Also, if you want to limit the user to interacting with local storage, you can set EXTRA_LOCAL_ONLY.

As for (2), you can create new files outside your package-specific directory with ACTION_CREATE_DOCUMENT, and you can select existing files with either intent. User-selected files can be deleted with DocumentsContract.deleteDocument().

And for (3), MediaDocumentsProvider built into the platform currently does not extend FLAG_SUPPORTS_WRITE for Photos, Videos, and Music.

Hope this helps. :)

Does Anyone knows Where this permission come from and how to grant this programmatically in Android?

I found it after too many searching in Stack Overflow , So there is a flag that call that dialog and get the uri of the storage ,but this way only works with android 7 to 10.
here is answer of my question :
question answer

How to do file operations (create/write/update/delete files) using the Flutter saf Package

If you get the folder access by using Storage Access Framework then you can not perform file handling operations on this folder by using the dart: 'dart: io' package.
Check URL: SAF root gives your application access to the corresponding storage, but only through the SAF API, not directly via the filesystem. Also, from Android 11 and above, without MANAGE_EXTERNAL_STORAGE permission, accessing data from external storage using java.io.File is almost completely deprecated.

I found two Packages that support Storage Access Framework in the flutter.

shared_storage: ^0.2.0

saf: ^1.0.3+3

shared_storage 0.2.0 provide us

Uri uri = await openDocumentTree(); 
List<UriPermission> persistedUris = await persistedUriPermissions();

and

/// Create a new file using the `SAF` API
final newDocumentFile = await createDocumentFile(
mimeType: 'text/plain',
content: 'My Plain Text Comment Created by shared_storage plugin',
displayName: 'CreatedBySharedStorageFlutterPlugin',
directory: anySelectedUriByTheOpenDocumentTreeAPI,
);

print(newDocumentFile);

By above method can create file by using writeAsString() instead of writeAsBytes(). But for creating an Image file we required writeAsBytes().

saf 1.0.3+3 having a method createFileAsBytes() in document_file.dart but not available for usage in current version.

But in the future, both packages will provide these APIs.

Solution:
For now, I have solved this issue by using both packages simultaneously.

Add packages in your pubspec.yaml:

shared_storage: ^0.2.0

saf: ^1.0.3+3

And use the following code

void createFileBySAF(String fileName, Uint8List uint8list) {

/*From: shared_storage: ^0.2.0*/
Uri uri = await openDocumentTree();

/*From: saf: ^1.0.3+3*/
Map<String, dynamic> result = await MethodChannel('com.ivehement.plugins/saf/documentfile').invokeMapMethod<String, dynamic>('createFile', <String, dynamic>{
'mimeType': 'any',
'content': uint8list,
'displayName': fileName,
'directoryUri': '$uri',
});
print(result);
}

For the Update and Delete operations find the usage in https://github.com/ivehement/saf/blob/master/lib/src/storage_access_framework/document_file.dart



Related Topics



Leave a reply



Submit