Docman
Document Manager: A Flutter plugin that simplifies file & directory operations on Android devices. Leveraging the Storage Access Framework (SAF) API, it provides seamless integration for picking, saving, sharing, and opening.
Install / Use
/learn @devdfcom/DocmanREADME
Document Manager (DocMan)
<a href="https://github.com/devdfcom/docman#readme"> <img src="https://github.com/user-attachments/assets/1f19d8af-3547-4825-836d-a596d5b16cf9" alt="DocMan logo" title="DocMan" align="right" height="150" /> </a>A Flutter plugin that simplifies file & directory operations on Android devices. Leveraging the Storage Access Framework (SAF) API, it provides seamless integration for files & directories operations, persisted permissions management, and more. Allows to set up own simple DocumentsProvider for specific directory within your app's storage.
🚀 Features
- Picker for files & directories.
- App directories path retriever (cache, files, external storage cache & files).
- Manage files & directories (create, delete, list, copy, move, open, save, share, etc.).
- Thumbnail generation for images, videos, pdfs.
- Stream-based file reading, directory listing.
- Separated actions that can be performed in the background, like with isolates or WorkManager.
- Persisted permissions management.
- No manifest permissions are required.
DocumentsProviderimplementation.
🤖 Supported Android versions
- Android 5.0 (API level 21) and above.
Example usage
import 'package:docman/docman.dart';
///Get the app's internal cache directory
/// Path Example: `/data/user/0/devdf.plugins.docman_example/cache`
Future<Directory?> getCachedDir() => DocMan.dir.cache();
///Pick a directory
Future<DocumentFile?> pickDir() => DocMan.pick.directory();
///Pick files & copy them to cache directory
Future<List<File>> pickFiles() => DocMan.pick.files(extensions: ['pdf', '.doc', 'docx']);
///Pick visual media (images & videos) - uses Android Photo Picker if available
Future<List<File>> pickMedia() => DocMan.pick.visualMedia(limit: 5, limitResultRestart: true);
///Get list of persisted permissions (directories only)
Future<List<Permission>> getPermissions() async => await DocMan.perms.list(files: false);
///DocumentFile used for file & directory operations
Future<void> dirOperationsExample() async {
//Instantiate a DocumentFile from saved URI
final dir = await DocumentFile.fromUri('content://com.android.externalstorage.documents/document/primary%3ADocMan');
//List directory files with mimeTypes filter
final List<DocumentFile> documents = await dir.listDocuments(mimeTypes: ['application/pdf']);
}
///And more... Check the documentation for more details.
📖 Documentation
API documentation is available at pub.dev. All public classes and methods are well-documented.
Note: To try the demos shown in the images run the example included in this plugin.
<ins>Table of Contents</ins>
- 🛠️ Installation
- 👆 Picker (🖼️ see examples)
- 📂 App Directories (🖼️ see examples)
- 🛡️ Persisted permissions (🖼️ see examples)
- 📄 DocumentFile (🖼️ see examples)
- 🗂️ DocumentsProvider (🖼️ see examples)
- 🗃️ DocMan Exceptions
- 📦 Changelog
- ⁉️ Help & Questions
- 🌱 Contributing
<a name="installation"></a>
🛠️ Installation
Add the following dependency to your pubspec.yaml file:
dependencies:
docman: ^1.2.0
Then run ➡️ flutter pub get.
👆 Picker
The picker provides a simple way to select files and directories from the device storage.
The Class DocManPicker or helper: DocMan.pick provides the
following methods:
Pick directory
Allows picking a directory from the device storage. You can specify the initial directory to start from.
[!WARNING] When picking directory, it also grants access to it. On Android 11 (API level 30) and higher it's <ins>impossible</ins> to grant access to root directories of sdCard, download folder, also it's <ins>impossible</ins> to select any file from: Android/data/ directory and all subdirectories, Android/obb/ directory and all subdirectories.
All restrictions are described here at developer.android.com
[!NOTE]
initDir: Option to set initial directory uri for picker is available since Android 8.0 (Api 26). If the option is not available, the picker will start from the default directory.
Future<DocumentFile?> pickBackupDir() => DocMan.pick.directory(initDir: 'content uri to start from');
Pick documents
Allows picking single or multiple documents. You can specify the initial directory to start from. Filter by MIME types & extensions, by location - only local files (no cloud providers etc.) or both. You can choose a limit strategy when picking multiple documents. Grant persisted permissions to the picked documents. The point of this is to get only the metadata of the documents, without copying them to the cache/files directory.
Future<List<DocumentFile>> pickDocuments() =>
DocMan.pick.documents(
initDir: ' content uri to start from',
mimeTypes: ['application/pdf'],
extensions: ['pdf', '.docx'],
localOnly: true,
grantPermissions: true,
limit: 5,
limitResultRestart: true,
limitRestartToastText: 'Pick maximum 5 items',
);
Pick files
Allows picking single or multiple files. The difference from Pick documents
is that it returns a list of File(s) saved in the cache directory.
First, it will try to copy to the external cache directory; if not available, then to the internal cache directory.
You can specify the initial directory to start from, filter by MIME types & extensions, by location - show only local files (no cloud providers etc.). You can choose a limit strategy when picking multiple documents.
Future<List<File>> pickFiles() =>
DocMan.pick.files(
initDir: 'content uri to start from',
mimeTypes: ['application/pdf', 'application/msword'],
extensions: ['pdf', '.doc', 'txt'],
localOnly: false,
//Set limit to 1 for single file picking
limit: 5,
limitResultCancel: true, //cancel with exception picking if limit is exceeded
);
Pick visualMedia
This is almost the same as Pick files. Allows picking visual media like images or videos. It uses the Android Photo Picker (VisualMediaPicker) if available. You can disable the visual media picker if needed. You can specify the initial directory to start from, filter by MIME types & extensions, by location - show only local files (no cloud providers etc.). You can choose a limit strategy when picking multiple documents. Allows setting image quality for compression. All picked files will be copied to the cache directory (external or internal).
Future<List<File>> pickVisualMedia() =>
DocMan.pick.visualMedia(
initDir: 'content uri to start from',
mimeTypes: ['image/*'],
extensions: ['jpg', '.png', 'webp'],
// used only for images, default is 100
imageQuality: 70,
//fallback to default file picker if visual media picker is not available
useVisualMediaPicker: true,
localOnly: true,
limit: 3,
//Android PhotoPicker has limit functionality, system file picker has limit 100
limitResultEmpty: true, //return empty list if limit is exceeded
);
<a name="picker-examples"></a>
<details> <summary style="font-weight: bold">🖼️ Picker examples (click for expand/collapse)</summary>| Picking directory
Related Skills
node-connect
346.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
