π Flutter SAF (Storage Access Framework) Helper
FlutterSaf is a helper class designed to simplify directory access and file operations using Androidβs Storage Access Framework (SAF) in Flutter.
It allows developers to easily request directory access, manage permissions, read file contents, and more β all through a unified API.
π Features
- β Request directory access
- β Check and release persisted permissions
- β Read file contents as bytes
- β Fetch list of files in a directory
- β Generate thumbnails for media files
π¦ Installation
Add this package and its dependencies:
dependencies:
flutter_saf:
Then run:
flutter pub get
π§© Usage
Step 1: Import the package
import 'package:flutter_saf/flutter_saf.dart';
Step 2: Initialize with a directory path
final flutterSaf = FlutterSaf(directory: '/storage/emulated/0/Download');
π API Reference & Examples
π getDirectory()
Returns the directory path provided during initialization.
print('Selected directory: ${flutterSaf.getDirectory()}');
π getUriString() and getUri()
Returns the directory URI in string or Uri form.
print('Directory URI string: ${flutterSaf.getUriString()}');
final uri = flutterSaf.getUri();
print('Directory URI object: $uri');
π requestDirectoryAccess()
Requests access to the directory.
If permission already exists, returns true; otherwise opens the picker.
final granted = await flutterSaf.requestDirectoryAccess(allowWriteAccess: true);
if (granted == true) {
print('Directory access granted!');
} else {
print('Access denied or cancelled.');
}
ποΈ getPersistedDirectoryPermissions()
Retrieves all persisted directory permissions as a list.
final permissions = await flutterSaf.getPersistedDirectoryPermissions();
permissions?.forEach((p) {
print('Persisted URI: ${p.uri}');
print('Read: ${p.isReadPermission}, Write: ${p.isWritePermission}');
});
π hasPersistedDirectoryPermission()
Checks whether your app already has access to the initialized directory.
final hasPermission = await flutterSaf.hasPersistedDirectoryPermission();
print('Has permission: $hasPermission');
π« releasePersistedDirectoryPermission()
Releases the directory permission previously granted by the user.
await flutterSaf.releasePersistedDirectoryPermission();
print('Permission released successfully.');
π getContent()
Reads and returns file content from the current directory as bytes.
final bytes = await flutterSaf.getContent();
if (bytes != null) {
print('File size: ${bytes.lengthInBytes} bytes');
}
π‘ Useful when reading files like PDFs, images, or documents.
π§Ύ getFilesUri()
Lists all files inside the selected directory.
final files = await flutterSaf.getFilesUri();
if (files != null && files.isNotEmpty) {
for (final file in files) {
print('File name: ${file.name}');
print('URI: ${file.uri}');
}
} else {
print('No files found.');
}
πΌοΈ getThumbnail(Uri fileUri, {int width, int height})
Generates a thumbnail for the specified file (commonly images or videos).
final uri = Uri.parse('content://com.android.providers.media.documents/document/image%3A12345');
final thumbnailBytes = await flutterSaf.getThumbnail(uri, width: 300, height: 300);
if (thumbnailBytes != null) {
print('Thumbnail generated successfully (${thumbnailBytes.length} bytes)');
}
π§ Example Use Case
void main() async {
final saf = FlutterSaf(directory: '/storage/emulated/0/Documents');
final accessGranted = await saf.requestDirectoryAccess();
if (accessGranted == true) {
final files = await saf.getFilesUri();
print('Found ${files?.length ?? 0} files in directory.');
}
}
π§© Models
DirectoryPermission
Represents a persisted permission entry.
| Property | Type | Description |
|---|---|---|
uri |
String | Directory URI |
isReadPermission |
bool | Whether read access is granted |
isWritePermission |
bool | Whether write access is granted |
persistedTime |
int | Time when the permission was granted |
DocumentFileModel
Represents a document/file entry.
| Property | Type | Description |
|---|---|---|
name |
String | File name |
uri |
String | File URI |
type |
String | MIME type |
size |
int | File size |
π§Ύ Logging
You can easily print the class details:
print(flutterSaf.toString());
// Output: FlutterSaf(directory: /storage/emulated/0/Download, uri: content://...)
π§βπ» Contributing
Pull requests and suggestions are welcome! If you encounter any issues, please open an issue on GitHub.
167d86b (chore: initial commit)