Saf class

Android Storage Access Framework client.

One class for everything SAF: directory/file pickers, persisted permissions, file management (list, stat, mkdirp, rename, copy, move, recursive walk), byte- and stream-based read/write, and bridging between SAF documents and local files.

final saf = Saf();
final dir = await saf.pickDirectory();
if (dir != null) {
  for (final f in await saf.list(dir.uri)) {
    print('${f.name} (${f.length} bytes)');
  }
}

Constructors

Saf()

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

child(String dirUri, List<String> names) Future<SafDocumentFile?>
Resolves a descendant by name segments, e.g. child(dir.uri, ['backups', 'config.json']). Returns null if any segment is missing.
closeFileDescriptor(int fd) Future<void>
Closes a file descriptor previously opened by openFileDescriptor.
copyDirToLocal(String dirUri, String destDirPath) Future<List<String>>
Copies the files directly inside dirUri into the local directory destDirPath (which must already exist — e.g. your app's getExternalStorageDirectory()), returning the local paths written.
copyTo(String uri, String destDirUri, {SafProgressCallback? onProgress}) Future<SafDocumentFile>
Copies a file or directory (recursively) into destDirUri.
copyToLocalFile(String srcUri, String destPath, {SafProgressCallback? onProgress}) Future<void>
Copies a SAF document to a local filesystem path (e.g. app cache), so the file can be handed to APIs that need a real path.
delete(String uri) Future<void>
Deletes the document at uri. Directories are deleted recursively.
exists(String uri) Future<bool>
Whether a document exists at uri.
list(String dirUri) Future<List<SafDocumentFile>>
Lists the children of dirUri with full metadata in a single query.
mkdirp(String dirUri, List<String> names) Future<SafDocumentFile>
Creates the directory path names under dirUri, creating intermediate directories as needed. Returns the deepest directory.
moveTo(String uri, String destDirUri, {SafProgressCallback? onProgress}) Future<SafDocumentFile>
Moves a file or directory (recursively) into destDirUri.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
openFileDescriptor(String uri, String mode) Future<SafOpenFd>
Opens a native file descriptor for uri in mode (one of r, w, rw, wt), returning its raw SafOpenFd.fd and /proc/self/fd/<fd> path for handing to path-based/native APIs.
pasteLocalFile(String srcPath, String destDirUri, String name, String mime, {bool overwrite = false, SafProgressCallback? onProgress}) Future<SafDocumentFile>
Copies a local file into a SAF directory.
persistedPermissions() Future<List<SafPersistedPermission>>
Lists all URI permissions the app currently persists.
pickDirectory({String? initialUri, bool writePermission = true, bool persistablePermission = true}) Future<SafDocumentFile?>
Opens the system directory picker (ACTION_OPEN_DOCUMENT_TREE).
pickFile({String? initialUri, List<String>? mimeTypes, bool persistablePermission = false}) Future<SafDocumentFile?>
Opens the system file picker (ACTION_OPEN_DOCUMENT) for one file.
pickFiles({String? initialUri, List<String>? mimeTypes, bool persistablePermission = false}) Future<List<SafDocumentFile>>
Opens the system file picker allowing multiple selection.
readFileBytes(String uri, {int? start, int? count}) Future<Uint8List>
Reads a file's bytes. Use start/count to read a range.
readFileStream(String uri, {int? start, int bufferSize = 4194304}) Future<Stream<Uint8List>>
Streams a file's bytes in chunks of bufferSize (default 4 MiB).
releasePersistedPermission(String uri) Future<void>
Releases a persisted URI permission previously taken by a picker.
rename(String uri, String newName) Future<SafDocumentFile>
Renames the document at uri to newName and returns it.
stat(String uri) Future<SafDocumentFile?>
Returns metadata for uri, or null if no document exists there.
thumbnail(String uri, int width, int height, int quality) Future<Uint8List?>
Requests a provider-generated thumbnail for uri, sized up to widthxheight and JPEG-encoded at quality (0-100).
toString() String
A string representation of this object.
inherited
walk(String dirUri) Stream<SafWalkEntry>
Recursively walks dirUri depth-first, emitting every descendant.
withFileDescriptor<T>(String uri, String mode, Future<T> action(SafOpenFd)) Future<T>
Opens a file descriptor for uri in mode, runs action with it, and always closes the descriptor afterwards — even if action throws.
writeFileBytes(String dirUri, String name, String mime, Uint8List data, {bool overwrite = false, bool append = false}) Future<SafDocumentFile>
Writes data as a file named name inside dirUri.
writeFileStream(String dirUri, String name, String mime, Stream<List<int>> source, {bool overwrite = false, bool append = false}) Future<SafDocumentFile>
Writes a whole source stream as a file in one call — no session bookkeeping required.

Operators

operator ==(Object other) bool
The equality operator.
inherited