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.
- 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.
DocumentsProvider
implementation.
- Android 5.0 (API level 21) and above.
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(uri: 'content://com.android.externalstorage.documents/document/primary%3ADocMan')
.get();
//List directory files with mimeTypes filter
final List<DocumentFile> documents = await dir.listDocuments(mimeTypes: ['application/pdf']);
}
///And more... Check the documentation for more details.
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.
- π οΈ Installation
- π Picker (πΌοΈ see examples)
- π App Directories (πΌοΈ see examples)
- π‘οΈ Persisted permissions (πΌοΈ see examples)
- π DocumentFile (πΌοΈ see examples)
- ποΈ DocumentsProvider (πΌοΈ see examples)
- ποΈ DocMan Exceptions
- π¦ Changelog
βοΈ Help & Questions- π± Contributing
Add the following dependency to your pubspec.yaml
file:
dependencies:
docman: ^1.0.0
Then run β‘οΈ flutter pub get
.
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:
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 impossible to grant access to root directories of sdCard, download folder, also it's impossible 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');
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',
);
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
);
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
);
πΌοΈ Picker examples (click for expand/collapse)
Picking directory | Picking documents |
---|---|
Picking files | Picking visualMedia |
---|---|
The plugin provides a way to get the app's internal & external directories,
like cache, files, data, external cache, external files, etc.
You can instantiate a DocManAppDirs class
or use the helper: DocMan.dir
to get the directories.
/// Get Application internal Cache Directory.
/// Path Example: `/data/user/0/devdf.plugins.docman_example/cache`
Future<Directory?> cache() => DocMan.dir.cache();
/// Get Application Files Directory.
/// The directory for storing files, rarely used.
/// Path Example: `/data/user/0/devdf.plugins.docman_example/files`
Future<Directory?> files() => DocMan.dir.files();
/// Get Application Data Directory.
/// Default Directory for storing data files of the app.
/// Path Example: `/data/user/0/devdf.plugins.docman_example/app_flutter`
Future<Directory?> data() => DocMan.dir.data();
/// Get Application External Cache Directory.
/// Path Example: `/storage/emulated/0/Android/data/devdf.plugins.docman_example/cache`
Future<Directory?> externalCache() => DocMan.dir.externalCache();
/// Get Application External Files Directory.
/// Path Example: `/storage/emulated/0/Android/data/devdf.plugins.docman_example/files`
Future<Directory?> filesExt() => DocMan.dir.filesExt();
During the app lifecycle, the cache (external or internal) directory can be filled with temporary files,
created by the plugin. When you pick files, visual media, or copy to cache, for example,
the plugin will create temporary files in the cache (external or internal) directory
in subdirectories like docManMedia
and docMan
.
To clean those directories, you can use the following method:
/// Clear Temporary Cache Directories.
///
/// Clears only the temp directories created by the plugin like `docManMedia` and `docMan`
/// in external & internal cache directories if exists.
///
/// Returns `true` if the directories were cleared successfully; otherwise, `false`.
Future<bool> clearPluginCache() => DocMan.dir.clearCache();
DocMan
provides a way to manage persisted permissions for directories & documents.
When you pick a directory or document with the parameter grantPermissions
set to true
,
its content URI gets a persistable permission grant.
Once taken, the permission grant will be remembered across device reboots.
If the grant has already been persisted, taking it again will just update the grant time.
You can instantiate a DocManPermissionManager class
or use the helper: DocMan.perms
to manage permissions.
Caution
Persistable permissions have limitations:
- Limited to 128 permissions per app for Android 10 and below
- Limited to 512 permissions per app for Android 11 and above
PersistedPermission
is a data class that holds information about the permission grant.
It is a representation of
the UriPermission Android class on Dart
side. It stores the uri
and time
of the permission grant, and whether it has read
or write
access.
final perm = PersistedPermission(
uri: 'content://com.android.externalstorage.documents/tree/primary%3ADocMan',
read: true,
write: true,
time: 1733260689869);
You can list or stream all persisted permissions. Also, you can filter permissions by files or directories or both.
/// Get list of all persisted permissions.
/// Optionally filter by files or directories.
Future<List<PersistedPermission>> listPerms({bool files = true, bool dirs = true}) =>
DocMan.perms.list(files: files, directories: dirs);
/// Stream all persisted permissions.
/// Optionally filter by files or directories.
Future<void> streamPerms() async {
final Stream<PersistedPermission> stream = DocMan.perms.listStream(files: false);
int countPerms = 0;
stream.listen((perm) {
countPerms++;
print(perm.toString());
}, onDone: () {
print('Stream Done, $countPerms permissions');
}, onError: (e) {
print('Error: $e');
});
}
You can list or stream all documents (DocumentFile
) with persisted permissions.
Also, you can filter documents by files or directories or both.
This method also removes the persisted permissions for the files/directories that no longer exist
(for example, the user deleted the file, through another app).
/// List all DocumentFiles with persisted permissions.
/// Optionally filter by files or directories.
Future<List<DocumentFile>> listDocumentsWithPerms({bool files = true, bool dirs = true}) =>
DocMan.perms.listDocuments(files: files, directories: dirs);
/// Stream all DocumentFiles with persisted permissions.
/// Optionally filter by files or directories.
Future<void> streamDocs() async {
final Stream<DocumentFile> stream = DocMan.perms.listDocumentsStream(directories: true, files: false);
int countDocs = 0;
stream.listen((doc) {
countDocs++;
print(doc.toString());
}, onDone: () {
print('Stream Done, $countDocs documents');
}, onError: (e) {
print('Error: $e');
});
}
You can release a single permission for a specific URI or all permissions.
/// Release persisted permission for specific URI.
Future<bool> releasePermission(String uri) => DocMan.perms.release(uri);
/// PersistedPermission class has helper method to release permission.
Future<void> permAction() async {
final PersistedPermission perm = await DocMan.perms
.list()
.first;
await perm.release();
}
/// Release all persisted permissions.
Future<bool> releaseAllPermissions() => DocMan.perms.releaseAll();
You can check if the URI has a persisted permission grant.
/// Check if URI has persisted permission grant.
Future<PersistedPermission?> hasPermission() =>
DocMan.perms.status('content://com.android.externalstorage.documents/tree/primary%3ADocMan');
You can validate persisted permissions for files or directories. It will check each uri in persisted permissions list and remove invalid permissions (for example, the user deleted the file/directory through system file manager).
/// Validate the persisted permissions list.
/// Returns `true` if the list was validated successfully, otherwise throws an error.
Future<bool> validatePermissions() => DocMan.perms.validateList();
πΌοΈ Persisted permissions examples (click for expand/collapse)
List/Stream Permissions | List/Stream Documents |
---|---|
DocumentFile
is a class that represents a file or directory in the device storage.
It's a dart representation of
the android DocumentFile.
It provides methods to perform file & directory operations like create, delete, list, copy, open, save, share, etc.
The purpose of it is to get the file's metadata like name, size, mime type, last modified, etc. and perform actions on
it without the need to copy each file in cache/files directory.
All supported methods are divided in extensions grouped by channels (Action, Activity, Events).
Note
Methods for directories are marked with π
, for files π
.
There are two ways to instantiate a DocumentFile
:
-
From the uri (content://), saved previously, with persisted permission.
Future<DocumentFile?> backupDir() => DocumentFile(uri: 'content://com.android.externalstorage.documents/tree/primary%3ADocMan').get();
Caution
In rarely cases DocumentFile
can be instantiated even if the uri doesn't have persisted permission.
For example uris like content://media/external/file/106
cannot be instantiated directly,
but if the file was picked through (DocMan.pick.visualMedia()
for example), it will be instantiated,
but most of the methods will throw an exception, you will be able only to read the file content.
-
From the app local
File.path
orDirectory.path
.Future<DocumentFile?> file() => DocumentFile(uri: 'path/to/file.jpg').get(); /// If directory doesn't exist, it will create all directories in the path. Future<DocumentFile?> dir() => DocumentFile(uri: 'path/to/some/directory/notCreatedYet').get();
Activity Methods are interactive methods which require user interaction.
Like open
, share
, saveTo
methods. All methods are called through Activity channel.
-
open
π
Open the file with supported app.If there are more than one app that can open files of this file type, the system will show a dialog to choose the app to open with. Action can be performed only on file & file must exist.
Future<bool> openFile(DocumentFile file) => file.open('Open with:');
-
share
π
Share the file with other apps.Future<bool> shareFile(DocumentFile file) => file.share('Share with:');
-
saveTo
π
Save the file to the selected directory.You can specify the initial directory to start from, whether to show only local directories or not, and delete the original file after saving. After saving, the method returns the saved
DocumentFile
.Future<DocumentFile?> saveFile(DocumentFile file) => file.saveTo( initDir: 'content uri to start from', //optional localOnly: true, deleteSource: true, );
Methods collection used for stream-based operations like reading files, listing directories, etc.
All methods are called through Events channel.
If DocumentFile
is a directory, you can list its files & subdirectories via stream,
if it's a file, you can read it via stream as bytes or string.
-
readAsString
π
Read the file content as string stream.Can be used only on file & file must exist. You can specify the encoding of the file content, buffer size or set the start position to read from.
Stream<String> readAsString(DocumentFile file) => file.readAsString(charset: 'UTF-8', bufferSize: 1024, start: 0);
-
readAsBytes
π
Read the file content as bytes stream.Can be used only on file & file must exist. You can specify the buffer size or set the start position to read from.
Stream<Uint8List> readAsBytes(DocumentFile file) => file.readAsBytes(bufferSize: (1024 * 8), start: 0);
-
listDocumentsStream
π
List the documents in the directory as stream.Can be used only on directory & directory must exist. You can specify the mimeTypes & extensions filter, to filter the documents by type, or filter documents by string in name.
Stream<DocumentFile> listDocumentsStream(DocumentFile dir) => dir.listDocumentsStream(mimeTypes: ['application/pdf'], extensions: ['pdf', '.docx'], nameContains: 'doc_');
Action methods are used for file & directory operations. All methods are called through Action channel, and can be performed in the background (with isolates or WorkManager).
-
permissions
π
π
Get the persisted permissions for the file or directory.Returns PersistedPermission instance or
null
if there are no persisted permissions.Future<PersistedPermission?> getPermissions(DocumentFile file) => file.permissions();
-
read
π
Read the entire file content as bytes.Can be used only on file & file must exist.
Future<Uint8List> readBytes(DocumentFile file) => file.read();
βΉοΈ If file is big, it's better to use stream-based method readAsBytes.
-
createDirectory
π
Create a new subdirectory with the specified name.Can be used only on directory & directory must exist & has write permission & flag
canCreate
istrue
. Returns the createdDocumentFile
directory.Future<DocumentFile?> createDir(DocumentFile dir) => dir.createDirectory('new_directory');
-
createFile
π
Create a new file with the specified name & content in the directory.Can be used only on directory & directory must exist & has write permission & flag
canCreate
istrue
. You can specify the content of the file as bytes or string, name must contain extension. It will try to determine the mime type from the extension, otherwise it will throw an exception. If the name contains extension only, like in example.txt
, name will be generated automatically. Example:.txt
->docman_file_18028.txt
. Returns the createdDocumentFile
file./// Create a new file with the specified name & String content in the directory. Future<DocumentFile?> createFile(DocumentFile dir) => dir.createFile(name: '.txt', content: 'Hello World!'); /// Create a new file with the specified name & bytes content in the directory. Future<DocumentFile?> createFileFromBytes(DocumentFile dir) => dir.createFile(name: 'test Document.pdf', bytes: Uint8List.fromList([1, 2, 3, 4, 5]));
-
listDocuments
π
List the documents in the directory.Can be used only on directory & directory must exist. You can specify the mimeTypes & extensions filter, to filter the documents by type, or filter documents by string in name.
Future<List<DocumentFile>> listDocuments(DocumentFile dir) => dir.listDocuments(mimeTypes: ['application/pdf'], extensions: ['pdf', '.docx'], nameContains: 'doc_');
βΉοΈ This method returns all documents in the directory, if list has many items, it's better to use stream-based method listDocumentsStream.
-
find
π
Find the document in the directory by name.Can be used only on directory & directory must exist. Search through
listDocuments
for the first document exact matching the given name. Returns null when no matching document is found.Future<DocumentFile?> findDocument(DocumentFile dir) => dir.find('file_name.jpg');
-
delete
π
π
Delete the file or directory. Can be used on both file & directory.Works only if the document exists & has permission to write & flag
canDelete
is set totrue
. If the document is a directory, it will delete all content recursively. Returnstrue
if the document was deleted.Future<bool> deleteFile(DocumentFile file) => file.delete(); Future<bool> deleteDir(DocumentFile dir) => dir.delete();
-
cache
π
Copy the file to the cache directory (external if available, internal otherwise).If file with same name already exists in cache, it will be overwritten. Works only if the document exists & has permission to read. Returns
File
instance of the cached file./// For all types of files Future<File?> cacheFile(DocumentFile file) => file.cache(); /// If file is image (jpg, png, webp) you can specify the quality of the image Future<File?> cacheImage(DocumentFile file) => file.cache(imageQuality: 70);
-
copyTo
π
Copy the file to the specified directory.File must exist & have flag
canRead
set totrue
. Destination directory must exist & have persisted permissions, or it can be local app directory likeDirectory.path
. Optionally You can specify the new name of the file, with or without extension. If something goes wrong, it will throw an exception & created file will be deleted.///Copy file to the the directory `DocumentFile` instance with persisted permission uri Future<DocumentFile?> copyFile(DocumentFile file) => file.copyTo('content://com.android.externalstorage.documents/tree/primary%3ADocMan', name: 'my new file copy'); ///Copy file to the the local app directory `Directory.path` Future<DocumentFile?> copyFileToLocalDir(DocumentFile file) => file.copyTo('/data/user/0/devdf.plugins.docman_example/app_flutter/myDocs', name: 'test_file.txt');
-
moveTo
π
Move the file to the specified directory.File must exist & have flag
canRead
&canDelete
set totrue
. Destination directory must exist & have persisted permissions, or it can be local app directory likeDirectory.path
. Optionally You can specify the new name of the file, with or without extension, otherwise the file will be moved with the same name. If something goes wrong, automatically will delete the created file. Returns theDocumentFile
instance of the moved file. After moving the file, the original file will be deleted.///Move file to the the directory `DocumentFile` instance with persisted permission uri Future<DocumentFile?> moveFile(DocumentFile file) => file.moveTo('content://com.android.externalstorage.documents/tree/primary%3ADocMan', name: 'moved file name'); ///Move file to the the local app directory `Directory.path` Future<DocumentFile?> moveFileToLocalDir(DocumentFile file) => file.moveTo('/data/user/0/devdf.plugins.docman_example/cache/TempDir', name: 'moved_file.txt');
-
thumbnail
π
Get the thumbnail of the file.Can be used only on file & file must exist & has flag
canThumbnail
set totrue
. You must specify the width & height of the thumbnail. Optionally you can specify the quality of the image and setpng
orwebp
totrue
to get the compressed image in that format, otherwise it will bejpeg
. Returns DocumentThumbnail instance of the thumbnail image ornull
if the thumbnail is not available. Commonly used for images, videos, pdfs.Future<DocumentThumbnail?> thumbnail(DocumentFile file) => file.thumbnail(width: 256, height: 256, quality: 70);
[!NOTE]
β οΈ Sometimes due to different document providers, thumbnail can have bigger dimensions, than requested. Some document providers may not support thumbnail generation.[!TIP]
β οΈ If file is local image, onlyjpg
,png
,webp
,gif
types are currently supported for thumbnail generation, in all other cases support depends on the document provider. -
thumbnailFile
π
Get the thumbnail of the file as aFile
.Same as
thumbnail
method, but returns the thumbnail image as aFile
instance, saved in the cache directory. First it will try to save to external cache directory, if not available, then to internal cache directory.Future<File?> thumbnailFile(DocumentFile file) => file.thumbnailFile(width: 192, height: 192, webp: true);
DocumentThumbnail
is a data class that holds information about the thumbnail image.
It stores the width
, height
of the image, and the bytes
(Uint8List) of the image.
Information about currently (temporarily) unsupported methods in the plugin.
Caution
π
rename
action was commented out due to the issue with the SAF API.
Very few Documents Providers support renaming files & after renaming, the document may not be found,
so it's better to use copy
& delete
actions instead.
πΌοΈ DocumentFile examples (click for expand/collapse)
Local file activity | Picked File actions |
---|---|
Picked Directory actions | Local Directory actions |
---|---|
DocMan
provides a way to set up a simple
custom DocumentsProvider
for your app. The main purpose of this feature is to share app files & directories with other apps,
by System File Picker UI
. You provide the name of the directory,
where your public files are stored. The plugin will create a custom DocumentsProvider for your app,
that will be accessible by other apps. You can customize it, and set the permissions for the files & directories.
Note
If you don't want to use the custom DocumentsProvider, you can just delete the provider.json
,
if it exists, in the assets
directory.
Tip
When you perform any kind of action on files or directories in the provider directory, Provider will reflect the changes in the System File Picker UI.
-
Create/Copy the
provider.json
file to theassets
directory in your app. You can find the example file in the plugin's example app. -
Update the
pubspec.yaml
file.flutter: assets: - assets/provider.json
All configuration is stored in the assets/provider.json
file.
Important
Once you set up the provider, do not change any parameter dynamically, otherwise the provider will not work correctly.
-
rootPath
The name of the directory where your public files are stored. This parameter is required. This is an entry point for the provider. Directory will be created automatically, if it doesn't exist. Plugin first will try to create the directory in the external storage (app files folder), if not available, then in the internal storage (app data folder - which isapp_flutter/
)Example values:
public_documents
,provider
,nested/public/path
.{ "rootPath": "public_documents" }
-
providerName
- The name of the provider that will be shown in the System UI, if null it will use the app name. Do not set long name, it will be truncated.{ "providerName": "DocMan Example" }
-
providerSubtitle
- The subtitle of the provider that will be shown in the System UI, if null it will be hidden.{ "providerSubtitle": "Documents & media files" }
-
mimeTypes
- List of mime types that the provider supports. Set this to null to show provider in all scenarios.{ "mimeTypes": ["image/*", "video/*"] }
-
extensions
- List of file extensions that the provider supports. Set this to null to show provider in all scenarios.{ "extensions": ["pdf", ".docx"] }
On the init, if you provide
mimeTypes
&extensions
, the plugin will check if the platform supports them & will combine in a single list & filter only supported types.
Note
If you set mimeTypes
for example to ["image/*"]
, when System File Picker UI
is opened by any other
app, which also wants to get images, it will show your provider in list of providers. But remember if you set
mimeTypes
or extensions
to specific types, but you store different types of files in the directory,
they will be also visible.
Important
In short: if you set mimeTypes
or extensions
,
you have to store only files of these types in the provider directory.
-
showInSystemUI
- Whether to show the provider in the System UI. If set tofalse
, the provider will be hidden. This is working only on Android 10 (Api 29) and above, on lower versions it will always be shown. -
supportRecent
- Whether to add provider files to theRecent
list. -
supportSearch
- Whether to include provider files in search in the System UI. -
maxRecentFiles
- Maximum number of recent files that will be shown in theRecent
list. Android max limit is 64, plugin default is 15. -
maxSearchResults
- Maximum number of search results that will be shown in the search list. Plugin default is 10.
π© Supported flags for directories:
Tip
You can skip the directories
section, if you plan to support all actions for directories.
Because by default all actions are set to true
, even if you don't provide them in the section.
create
- Whether the provider supports creation of new files & directories within it.delete
- Whether the provider supports deletion of files & directories.move
- Whether documents in the provider can be moved.rename
- Whether documents in the provider can be renamed.copy
- Whether documents in the provider can be copied.
Section for directories in the provider.json
file:
{
"directories": {
"create": true,
"delete": true,
"move": true,
"rename": true,
"copy": true
}
}
π³οΈ Supported flags for files:
Tip
You can skip the files
section, if you plan to support all actions for directories.
Because by default all actions are set to true
, even if you don't provide them in the section.
delete
- Whether the provider supports deletion of files & directories.move
- Whether documents in the provider can be moved.rename
- Whether documents in the provider can be renamed.write
- Whether documents in the provider can be modified.copy
- Whether documents in the provider can be copied.thumbnail
- Indicates that documents can be represented as a thumbnails.- The provider supports generating custom thumbnails for videos and PDFs.
- Thumbnails for images are generated by system.
- All thumbnails, generated by the provider, are cached in the
thumbs
directory under thedocManMedia
directory. - You can clear the thumbnail cache using
DocMan.dir.clearCache()
.
Section for files in the provider.json
file:
{
"files": {
"delete": true,
"move": true,
"rename": true,
"write": true,
"copy": true,
"thumbnail": true
}
}
or short version, if all actions are supported:
{
"files": {
"delete": false
}
}
ποΈ Full Example of the `provider.json` (click for expand/collapse)
{
"rootPath": "nested/provider_folder",
"providerName": "DocMan Example",
"providerSubtitle": "Documents & media files",
"mimeTypes": [
"image/*"
],
"extensions": [
".pdf",
"mp4"
],
"showInSystemUI": true,
"supportRecent": true,
"supportSearch": true,
"maxRecentFiles": 20,
"maxSearchResults": 20,
"directories": {
"create": false,
"delete": true,
"move": true,
"rename": true,
"copy": true
},
"files": {
"delete": true,
"move": true,
"rename": true,
"write": true,
"copy": true,
"thumbnail": true
}
}
πΌοΈ DocumentsProvider examples (click for expand/collapse)
Side menu view in System File Manager | Visibility in Recents |
---|---|
DocumentsProvider through Intent | DocumentsProvider via File Manager |
---|---|
DocMan
provides a set of exceptions that can be thrown during the plugin operation.
DocManException
- Base exception for all exceptions.
Common exceptions for all channels:
AlreadyRunningException
Thrown when the same method is already in progress.NoActivityException
Thrown when the activity is not available. For example when you try to perform activity actions likeopen
,share
,saveTo
orpick
& no activity found to handle the request.
π DocManAppDirs()
(DocMan.dir
) exceptions:
AppDirPathException
Thrown when the app directory path is not found. For example if device doesn't have external storage.AppDirActionException
Thrown when app tries to perform unimplemented action on app directory.
π DocManPicker()
(DocMan.pick
) exceptions:
PickerMimeTypeException
Thrown forDocMan.pick.visualMedia()
method, when mimeTypes are not supported.PickerMaxLimitException
Thrown forDocMan.pick.visualMedia()
method. Whenlimit
parameter is greater than max allowed by the platform, currently it uses MediaStore.getPickImagesMaxLimit on supported devices (Android 11 & above), otherwise it forces the limit to 100.PickerCountException
Thrown when you set picker parameterlimitResultCancel
totrue
. This exception has 2 String properties:count
- number of picked files,limit
- the limit set. For example when you pick 5 files, butlimit
is set to 3 andlimitResultCancel
istrue
.
π DocumentFile
exceptions:
DocumentFileException
Base exception for allDocumentFile
exceptions thrown by the plugin.
π‘οΈ DocManPermissionManager()
(DocMan.perms
) exceptions:
PermissionsException
Base exception thrown by the permissions' manager for all methods.
Please see CHANGELOG.md for more information on what has changed recently.
Start a new discussion in the Discussions Tab.
Any contributions you make are greatly appreciated.
Just fork the repository and create a pull request.
For major changes, please first start a discussion in the Discussions Tab to discuss what you would like to change.
βΌοΈ By submitting a patch, you agree to allow the project owner(s) to license your work under the terms of theMIT License
.
π Thank you!