ym_open_file_plus 1.0.0
ym_open_file_plus: ^1.0.0 copied to clipboard
Open local files with the platform's default app on Android, iOS, Linux, macOS, Windows, and the web.
ym_open_file_plus #
Open a local file with the device's default application from Flutter. The plugin supports Android, iOS, Linux, macOS, Windows, and web.
This package is a maintained fork of open_file with a narrow Android permission model and a Dart-only desktop implementation.
Supported platforms #
| Platform | Implementation | Minimum |
|---|---|---|
| Android | ACTION_VIEW + secure FileProvider |
Android 6.0 (API 23) |
| iOS | UIDocumentInteractionController |
iOS 13 |
| Linux | xdg-open or another desktop opener |
Flutter 3.44.8 |
| macOS | open |
Flutter 3.44.8 |
| Windows | Win32 ShellExecuteW |
Flutter 3.44.8 |
| Web | Browser navigation in a new tab | Flutter 3.44.8 |
Installation #
dependencies:
ym_open_file_plus: ^1.0.0
flutter pub get
Usage #
import 'package:ym_open_file_plus/ym_open_file_plus.dart';
final result = await OpenFile.open('/path/to/report.pdf');
switch (result.type) {
case ResultType.done:
print('Opened');
case ResultType.fileNotFound:
print('File does not exist');
case ResultType.noAppToOpen:
print('No compatible application is installed');
case ResultType.permissionDenied:
print('The host app cannot read this file');
case ResultType.error:
print(result.message);
}
You can provide an explicit MIME type on Android and a Uniform Type Identifier on iOS:
await OpenFile.open(
'/path/to/report.pdf',
type: 'application/pdf',
uti: 'com.adobe.pdf',
);
OpenFile.open returns an OpenResult with a stable ResultType and a diagnostic message. The result means that the platform accepted the open request; it does not guarantee that the user finished viewing the document.
Android storage and permissions #
The plugin does not request broad storage permissions and does not declare MANAGE_EXTERNAL_STORAGE. This is intentional.
For the most reliable modern Android flow, obtain a user-selected content:// URI through the Storage Access Framework and pass that URI to OpenFile.open. For a normal file path, the host app must already have read access to the file. The plugin shares it through a temporary, read-only FileProvider URI.
If your app intentionally reads legacy shared storage on Android 9 or lower, declare the permission in the app (not in this plugin) and scope it to the supported API level:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
To open an APK, the host app must be allowed to request package installs and declare the permission required by Android:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Google Play restricts this permission to apps whose core functionality requires package installation. Do not add it unless your app qualifies.
iOS #
Pass an absolute local file path. iOS presents a Quick Look preview when possible and otherwise presents the system Open In menu. The optional uti argument lets you override the document type.
Desktop #
Linux uses xdg-open by default:
await OpenFile.open('/tmp/report.pdf', linuxDesktopName: 'xdg');
linuxByProcess remains available for source compatibility with older releases; the current implementation always uses an argument-safe asynchronous process invocation, so paths containing spaces and shell metacharacters are handled safely.
Web #
Browsers cannot read arbitrary paths on the user's local filesystem. On web, pass an http, https, blob, or data URL and call the method directly from a user gesture:
await OpenFile.open('https://example.com/report.pdf');
Popup blockers can prevent a new tab from opening. A successful web result means that the browser accepted the navigation request.
Requirements #
- Dart SDK 3.11 or newer
- Flutter 3.44.8 or newer
- Android API 23 or newer
- iOS 13 or newer
License #
Copyright © 2026 Yash Manghnani. See LICENSE.