Last updated:
0 purchases
media extension
media_extension #
Plugin to help a Flutter application behave like a native gallery, by ente.
Features #
Allows to identify and handle invocation from a different app, along with details of the intent-action with which it was triggered (PICK / EDIT / VIEW). You can also use the setResult method to pass the URI of the selected media file to the requesting app, by creating a temporary copy within the content-provider path.
Ability to open an image with an third-party app (gallery, editor, wallpaper manager, etc.)
Implementation #
Native code invokes Flutter code by invoking the Flutter method from onAttachedEngineMethod, which returns the mode asynchronously. We use a Completer in the Dart code to get the status and set the mode of the app.
While behaving as a Gallery, the URI of the chosen image from the applications document storage directory and another method call is made to native code with the URI as the parameter.
We create a temporary file in our cache-directory with the received URI, and grants other applications permission to read from that directory. Once the content://uri (Content Provider) is created the result is sent to the requested activity via the intent.
DataTypes Descriptions #
Types
Fields
IntentAction
enumeration of main, pick, edit, view
MediaExtentionAction
IntentAction action [type of intent-action which invoked the app] String? uri [uri of the image sent by other app with the intent]
Method Descriptions #
Methods
Parameters
Return
getIntentAction
MediaExtentionAction
setResult
String uri [path of the file selected]
void
setAs
String uri [path of the file selected] String mimeType [mimeType of the file selected]
void
openWith
String uri [path of the file selected]String mimeType [mimeType of the file selected]
void
edit
String uri [path of the file selected]String mimeType [mimeType of the file selected]
void
Getting started #
To use this plugin:
Run the following command in terminal
flutter pub get media_extension
copied to clipboard
Or
Add the following in pubspec.yaml file
dependencies:
flutter:
sdk: flutter
media_extension:
copied to clipboard
Add the following in android/src/main/res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
<cache-path
name="embedded"
path="." />
</paths>
copied to clipboard
Add the following in android/src/main/AndroidManifest.xml
<application>
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
</application>
copied to clipboard
Example #
class MyAppState extends State<MyApp> {
final imgUrl = "https://cdn-chat.sstatic.net/chat/img/404_funny_hats.jpg";
IntentAction _intentAction = IntentAction.main;
final _mediaExtensionPlugin = MediaExtension();
final _downloadHelper = DownloadHelper(Dio());
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
IntentAction intentAction = IntentAction.main;
try {
final actionResult = await _mediaExtensionPlugin.getIntentAction();
intentAction = actionResult.action!;
} on PlatformException {
intentAction = IntentAction.unknown;
}
if (!mounted) return;
setState(() {
_intentAction = intentAction;
});
}
Future<String> _getLocalFile(String filename) async {
var tempDir = await getTemporaryDirectory();
String fullPath = "${tempDir.path}/image.jpg";
await _downloadHelper.downloadToFile(imgUrl, fullPath);
return fullPath;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Intent Action is: $_intentAction\n'),
FutureBuilder(
future: _getLocalFile("image.jpg"),
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
return snapshot.data != null
? GestureDetector(
child: Image.file(File(snapshot.data!)),
onTap: () async {
if (_intentAction == IntentAction.pick) {
_mediaExtensionPlugin
.setResult("file://${snapshot.data!}");
}
},
)
: Container();
}),
GestureDetector(
child: Text(
'Set as',
style: Theme.of(context).textTheme.headline4,
),
onTap: () async {
var tempDir = await getTemporaryDirectory();
String fullPath = "${tempDir.path}/image.jpg'";
await _downloadHelper.downloadToFile(imgUrl, fullPath);
try {
final isDOne = await _mediaExtensionPlugin.setAs(
"file://$fullPath", "image/*");
debugPrint("Is done $isDOne");
} on PlatformException {
debugPrint("Some error");
}
},
),
GestureDetector(
child: Text(
'Edit',
style: Theme.of(context).textTheme.headline4,
),
onTap: () async {
var tempDir = await getTemporaryDirectory();
String fullPath = "${tempDir.path}/image.jpg'";
await _downloadHelper.downloadToFile(imgUrl, fullPath);
try {
final isDOne = await _mediaExtensionPlugin.edit(
"file://$fullPath", "image/*");
debugPrint("Is done $isDOne");
} on PlatformException {
debugPrint("Some error");
}
},
),
GestureDetector(
child: Text(
'Open With',
style: Theme.of(context).textTheme.headline4,
),
onTap: () async {
var tempDir = await getTemporaryDirectory();
String fullPath = "${tempDir.path}/image.jpg'";
await _downloadHelper.downloadToFile(imgUrl, fullPath);
try {
final result = await _mediaExtensionPlugin.openWith(
"file://$fullPath", "image/*");
debugPrint("Is done $result");
} on PlatformException {
debugPrint("Some error");
}
},
),
],
),
),
),
);
}
}
copied to clipboard
Issues/Upcoming Changes #
Implement setResults method for multiple selection of images for ACTION_PICK intent.
Credits #
This plugin wouldn't be possible without the following:
aves : Most of the methods in the plugin are inspired from this repository
License #
MIT
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.