Skip to content

saf

One class for the Android Storage Access Framework โ€” pickers, persisted permissions, file management, streaming read/write, recursive walk, and progress.

Flutter โ‰ฅ 3.10 Dart โ‰ฅ 3.0 minSdk 21 pana 150/150 MIT
final saf = Saf();

final dir = await saf.pickDirectory();          // one prompt, persists across restarts
if (dir == null) return;

for (final f in await saf.list(dir.uri)) {
  print('${f.name} ยท ${f.length} B ยท ${f.mimeType}');
}

final doc = await saf.writeFileBytes(
    dir.uri, 'hello.txt', 'text/plain', utf8.encode('hi') as Uint8List);
final bytes = await saf.readFileBytes(doc.uri);

๐Ÿ“‚ One package

Everything SAF in a single Saf class โ€” no pairing two libraries.

๐Ÿ”’ Persisted permissions

Grant once, reuse across app restarts. List grants with persistedPermissions().

๐ŸŒŠ Streaming I/O

readFileStream and one-call writeFileStream for large files โ€” no session bookkeeping.

๐Ÿšถ Recursive walk

walk() streams a whole directory tree; copyTo/moveTo recurse with progress.

๐Ÿ”— Descriptors & thumbnails

openFileDescriptor / withFileDescriptor hand native APIs a live /proc/self/fd path; thumbnail() returns provider JPEG previews.

๐ŸŽฏ Typed errors

SafPermissionException, SafNotFoundException, โ€ฆ instead of raw PlatformException.

๐Ÿ“ฑ Broad support

Dart โ‰ฅ 3.0, Flutter โ‰ฅ 3.10, Android minSdk 21 โ€” wider than the alternatives.

Where to next