path_manager 0.6.0
path_manager: ^0.6.0 copied to clipboard
Plugin for getting commonly used locations on host file system via FFI
Path Manager #
A plugin providing unified access to commonly used host filesystem directories on Android, iOS, and macOS.
This plugin leverages direct native interop using Java Native Interface (JNI) on Android, and Objective-C FFI on iOS and macOS.
Platform & Method Support #
| Method | Android | iOS | macOS | Description |
|---|---|---|---|---|
getTemporaryDirectory() |
✅ | ✅ | ✅ | Temporary directory for cache files (subject to OS cleanup). |
getApplicationSupportDirectory() |
✅ | ✅ | ✅ | Application-created directory for app state, databases, etc. |
getApplicationDocumentsDirectory() |
✅ | ✅ | ✅ | User-accessible directory for persistent documents/profiles. |
getCachesDirectory() |
✅ | ✅ | ✅ | Cache directory (persists longer than temporary files). |
getApplicationNoBackupDirectory() |
✅ | ✅ | ✅ | Resolves a default directory that is excluded from backups. |
setApplicationPathIsExcludedFromBackup(...) |
❌ Throws | ✅ | ✅ | Programmatically toggles the backup exclusion flag. |
Features #
- Direct interop: Built completely with JNI and FFI interop—no MethodChannels.
- Tree shakeable: Platform-specific code and dependencies are only compiled and included for their target platform.
- Dedicated No-Backup Directories: Provides a default folder named
__no_backup__that is automatically marked for exclusion from platform backup systems. - Custom exclusions: Mark any arbitrary file or folder on iOS/macOS to be skipped during iCloud/iTunes backups.
Installation #
Add path_manager to your pubspec.yaml dependencies:
dependencies:
path_manager:
path: ^0.6.0
Then run:
flutter pub get
Configuration #
iOS & macOS #
No additional setup is required. The plugin programmatically sets the NSURLIsExcludedFromBackupKey resource key using iOS/macOS Foundation APIs when managing exclusions.
Android #
On Android, programmatic runtime backup exclusion on arbitrary filesystem entities is not supported by the OS. Instead, Android backup exclusions are configured statically via resource XML files.
To exclude the default __no_backup__ directory (which resolves to app_support_path/__no_backup__) from Android Auto Backup and Device-to-Device transfer, follow these setup steps:
1. Define Backup Rules (Android 11 and lower)
Create a file named backup_rules.xml in your Android project's resource directory (android/app/src/main/res/xml/backup_rules.xml):
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<!-- Exclude the __no_backup__ subdirectory inside the application files directory -->
<exclude domain="file" path="__no_backup__" />
</full-backup-content>
2. Define Data Extraction Rules (Android 12 / API 31 and above)
Create a file named data_extraction_rules.xml in your Android project's resource directory (android/app/src/main/res/xml/data_extraction_rules.xml):
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<!-- Exclude from Cloud Backups -->
<exclude domain="file" path="__no_backup__" />
</cloud-backup>
<device-transfer>
<!-- Exclude from Device-to-Device Transfer -->
<exclude domain="file" path="__no_backup__" />
</device-transfer>
</data-extraction-rules>
3. Register XML Rules in AndroidManifest.xml
In your android/app/src/main/AndroidManifest.xml file, link the rules inside the <application> element:
<application
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:dataExtractionRules="@xml/data_extraction_rules"
... >
Usage #
1. Retrieving Standard Directories #
import 'package:path_manager/path_manager.dart';
// Retrieve paths as standard dart:io Directory instances
final Directory temp = await PathManager.getTemporaryDirectory();
final Directory support = await PathManager.getApplicationSupportDirectory();
final Directory docs = await PathManager.getApplicationDocumentsDirectory();
final Directory caches = await PathManager.getCachesDirectory();
print('Support Dir: ${support.path}');
2. Getting the Dedicated No-Backup Directory #
The getApplicationNoBackupDirectory() method provides a default directory. If the directory does not exist, it is automatically created and (on Apple platforms) marked as excluded from backups.
import 'dart:io';
import 'package:path_manager/path_manager.dart';
try {
final Directory noBackupDir = await PathManager.getApplicationNoBackupDirectory();
final File localConfig = File('${noBackupDir.path}/settings.json');
await localConfig.writeAsString('{"offline_mode": true}');
print('Saved sensitive offline settings to: ${noBackupDir.path}');
} on BackupExclusionConflictException catch (e) {
// Occurs if the __no_backup__ folder exists but was manually un-excluded
print('Conflict detected: ${e.message}');
} on MissingPlatformDirectoryException catch (e) {
print('Failed to resolve directory: ${e.message}');
}
3. Programmatic Backup Exclusion (iOS & macOS Only) #
You can programmatically exclude individual files or directories on iOS and macOS.
import 'dart:io';
import 'package:path_manager/path_manager.dart';
final Directory docsDir = await PathManager.getApplicationDocumentsDirectory();
final File localDatabase = File('${docsDir.path}/app_db.sqlite');
try {
// Exclude the SQLite file from iCloud/iTunes backups
await PathManager.setApplicationPathIsExcludedFromBackup(localDatabase.path, true);
print('Successfully excluded local database from backups.');
} on UnsupportedError catch (e) {
// Thrown on Android
print('Programmatic exclusions are not supported on this platform: ${e.message}');
} on FileSystemException catch (e) {
// Thrown if the target file/directory does not exist
print('Filesystem error: ${e.message}');
}
Contributing #
We welcome contributions to this project!
Setting Up For Local Development #
- Clone the repository and run dependencies setup:
flutter pub get - Generate FFI/JNI bindings:
- For Android (requires
JAVA_HOMEpointing to a JDK):dart run tools/jnigen.dart - For iOS/macOS:
dart run tools/ffigen.dart
- For Android (requires
- Format all files before pushing:
dart format .
Running Tests #
Run the test suite on your development machine (macOS/Linux/Windows):
dart test
License #
This package is licensed under the MIT License. See LICENSE for more details.