Commit c778b11d authored by zhouteng's avatar zhouteng

multiple images share for android

parent 62008733
...@@ -4,13 +4,15 @@ import android.Manifest; ...@@ -4,13 +4,15 @@ import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
...@@ -23,10 +25,10 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi ...@@ -23,10 +25,10 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
/// the authorities for FileProvider /// the authorities for FileProvider
private static final int CODE_ASK_PERMISSION = 100; private static final int CODE_ASK_PERMISSION = 100;
private static final String CHANNEL = "share_extend"; private static final String CHANNEL = "com.zt.shareextend/share_extend";
private final Registrar mRegistrar; private final Registrar mRegistrar;
private String text; private List<String> list;
private String type; private String type;
public static void registerWith(Registrar registrar) { public static void registerWith(Registrar registrar) {
...@@ -48,40 +50,41 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi ...@@ -48,40 +50,41 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
throw new IllegalArgumentException("Map argument expected"); throw new IllegalArgumentException("Map argument expected");
} }
// Android does not support showing the share sheet at a particular point on screen. // Android does not support showing the share sheet at a particular point on screen.
share((String) call.argument("text"), (String) call.argument("type")); share((List) call.argument("list"), (String) call.argument("type"));
result.success(null); result.success(null);
} else { } else {
result.notImplemented(); result.notImplemented();
} }
} }
private void share(String text, String type) { private void share(List<String> list, String type) {
if (text == null || text.isEmpty()) { if (list == null || list.isEmpty()) {
throw new IllegalArgumentException("Non-empty text expected"); throw new IllegalArgumentException("Non-empty list expected");
} }
this.text = text; this.list = list;
this.type = type; this.type = type;
Intent shareIntent = new Intent(); Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if ("text".equals(type)) { if ("text".equals(type)) {
shareIntent.putExtra(Intent.EXTRA_TEXT, text); shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, list.get(0));
shareIntent.setType("text/plain"); shareIntent.setType("text/plain");
} else { } else {
File f = new File(text); if (ShareUtils.shouldRequestPermission(list)) {
if (!f.exists()) { if (!checkPermission()) {
throw new IllegalArgumentException("file not exists");
}
if (ShareUtils.shouldRequestPermission(text)) {
if (!checkPermisson()) {
requestPermission(); requestPermission();
return; return;
} }
} }
Uri uri = ShareUtils.getUriForFile(mRegistrar.activity(), f, type); ArrayList<Uri> uriList = new ArrayList<>();
for (String path : list) {
File f = new File(path);
Uri uri = ShareUtils.getUriForFile(mRegistrar.activity(), f, type);
uriList.add(uri);
}
if ("image".equals(type)) { if ("image".equals(type)) {
shareIntent.setType("image/*"); shareIntent.setType("image/*");
...@@ -90,9 +93,18 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi ...@@ -90,9 +93,18 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
} else { } else {
shareIntent.setType("application/*"); shareIntent.setType("application/*");
} }
shareIntent.putExtra(Intent.EXTRA_STREAM, uri); if (uriList.size() == 1) {
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uriList.get(0));
} else {
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
}
} }
startChooserActivity(shareIntent);
}
private void startChooserActivity(Intent shareIntent) {
Intent chooserIntent = Intent.createChooser(shareIntent, null /* dialog title optional */); Intent chooserIntent = Intent.createChooser(shareIntent, null /* dialog title optional */);
if (mRegistrar.activity() != null) { if (mRegistrar.activity() != null) {
mRegistrar.activity().startActivity(chooserIntent); mRegistrar.activity().startActivity(chooserIntent);
...@@ -102,12 +114,9 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi ...@@ -102,12 +114,9 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
} }
} }
private boolean checkPermisson() { private boolean checkPermission() {
if (ContextCompat.checkSelfPermission(mRegistrar.context(), Manifest.permission.WRITE_EXTERNAL_STORAGE) return ContextCompat.checkSelfPermission(mRegistrar.context(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) { == PackageManager.PERMISSION_GRANTED;
return true;
}
return false;
} }
private void requestPermission() { private void requestPermission() {
...@@ -117,7 +126,7 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi ...@@ -117,7 +126,7 @@ public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, Plugi
@Override @Override
public boolean onRequestPermissionsResult(int requestCode, String[] perms, int[] grantResults) { public boolean onRequestPermissionsResult(int requestCode, String[] perms, int[] grantResults) {
if (requestCode == CODE_ASK_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == CODE_ASK_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
share(text, type); share(list, type);
} }
return false; return false;
} }
......
...@@ -11,13 +11,14 @@ import android.provider.MediaStore; ...@@ -11,13 +11,14 @@ import android.provider.MediaStore;
import android.text.TextUtils; import android.text.TextUtils;
import java.io.File; import java.io.File;
import java.util.List;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
public class ShareUtils { public class ShareUtils {
/// get the uri for file /// get the uri for file
public static Uri getUriForFile(Context context, File file, String type) { static Uri getUriForFile(Context context, File file, String type) {
String authorities = context.getPackageName() + ".shareextend.fileprovider"; String authorities = context.getPackageName() + ".shareextend.fileprovider";
...@@ -51,7 +52,16 @@ public class ShareUtils { ...@@ -51,7 +52,16 @@ public class ShareUtils {
return uri; return uri;
} }
public static boolean shouldRequestPermission(String path) { static boolean shouldRequestPermission(List<String> pathList) {
for (String path : pathList) {
if (shouldRequestPermission(path)) {
return true;
}
}
return false;
}
static boolean shouldRequestPermission(String path) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isPathInExternalStorage(path); return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isPathInExternalStorage(path);
} }
...@@ -121,7 +131,7 @@ public class ShareUtils { ...@@ -121,7 +131,7 @@ public class ShareUtils {
* @param audioFile * @param audioFile
* @return content Uri * @return content Uri
*/ */
public static Uri getAudioContentUri(Context context, File audioFile) { private static Uri getAudioContentUri(Context context, File audioFile) {
String filePath = audioFile.getAbsolutePath(); String filePath = audioFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.DATA + "=? ", new String[]{MediaStore.Audio.Media._ID}, MediaStore.Audio.Media.DATA + "=? ",
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that <!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method. calls FlutterMain.startInitialization(this); in its onCreate method.
......
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/zhouteng/Android/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/zhouteng/flutter-demos/ShareExtend/example"
export "FLUTTER_TARGET=/Users/zhouteng/flutter-demos/ShareExtend/example/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "FLUTTER_FRAMEWORK_DIR=/Users/zhouteng/Android/flutter/bin/cache/artifacts/engine/ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "TRACK_WIDGET_CREATION=true"
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
11803D6D88B2BFDA33D6F683 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A809B722E3E92D8A211E93E2 /* libPods-Runner.a */; }; 11803D6D88B2BFDA33D6F683 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A809B722E3E92D8A211E93E2 /* libPods-Runner.a */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
...@@ -38,9 +37,9 @@ ...@@ -38,9 +37,9 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
07029D33E422EE11C426D7C7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
...@@ -56,6 +55,7 @@ ...@@ -56,6 +55,7 @@
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A809B722E3E92D8A211E93E2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A809B722E3E92D8A211E93E2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CD456C76FAC541BD38BB2841 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -83,7 +83,6 @@ ...@@ -83,7 +83,6 @@
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
3B80C3931E831B6300D905FE /* App.framework */, 3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEBA1CF902C7004384FC /* Flutter.framework */,
...@@ -140,6 +139,8 @@ ...@@ -140,6 +139,8 @@
A73596DA6A4E5A47E033894D /* Pods */ = { A73596DA6A4E5A47E033894D /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
07029D33E422EE11C426D7C7 /* Pods-Runner.debug.xcconfig */,
CD456C76FAC541BD38BB2841 /* Pods-Runner.release.xcconfig */,
); );
name = Pods; name = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -209,7 +210,6 @@ ...@@ -209,7 +210,6 @@
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
...@@ -269,7 +269,7 @@ ...@@ -269,7 +269,7 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
...@@ -278,7 +278,7 @@ ...@@ -278,7 +278,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
......
import 'package:flutter/material.dart';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:share_extend/share_extend.dart'; import 'package:share_extend/share_extend.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
void main() => runApp(new MyApp()); void main() => runApp(MyApp());
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
@override @override
_MyAppState createState() => new _MyAppState(); _MyAppState createState() => _MyAppState();
} }
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
...@@ -20,22 +22,23 @@ class _MyAppState extends State<MyApp> { ...@@ -20,22 +22,23 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new MaterialApp( return MaterialApp(
home: new Scaffold( home: Scaffold(
appBar: new AppBar( appBar: AppBar(
title: const Text('Plugin example app'), title: const Text('Plugin example app'),
), ),
body: Container( body: Container(
child: new Center( child: Center(
child: new Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
new RaisedButton( RaisedButton(
onPressed: () { onPressed: () {
ShareExtend.share("share text", "text"); ShareExtend.share("share text", "text");
}, },
child: new Text("share text"), child: Text("share text"),
), ),
new RaisedButton( RaisedButton(
onPressed: () async { onPressed: () async {
File f = await ImagePicker.pickImage( File f = await ImagePicker.pickImage(
source: ImageSource.gallery); source: ImageSource.gallery);
...@@ -43,9 +46,9 @@ class _MyAppState extends State<MyApp> { ...@@ -43,9 +46,9 @@ class _MyAppState extends State<MyApp> {
ShareExtend.share(f.path, "image"); ShareExtend.share(f.path, "image");
} }
}, },
child: new Text("share image"), child: Text("share image"),
), ),
new RaisedButton( RaisedButton(
onPressed: () async { onPressed: () async {
File f = await ImagePicker.pickVideo( File f = await ImagePicker.pickVideo(
source: ImageSource.gallery); source: ImageSource.gallery);
...@@ -53,13 +56,19 @@ class _MyAppState extends State<MyApp> { ...@@ -53,13 +56,19 @@ class _MyAppState extends State<MyApp> {
ShareExtend.share(f.path, "video"); ShareExtend.share(f.path, "video");
} }
}, },
child: new Text("share video"), child: Text("share video"),
), ),
new RaisedButton( RaisedButton(
onPressed: () { onPressed: () {
_shareApplicationDocumentsFile(); _shareApplicationDocumentsFile();
}, },
child: new Text("share file"), child: Text("share file"),
),
RaisedButton(
onPressed: () {
_shareMultipleImages();
},
child: Text("share multiple images"),
), ),
], ],
), ),
...@@ -69,10 +78,20 @@ class _MyAppState extends State<MyApp> { ...@@ -69,10 +78,20 @@ class _MyAppState extends State<MyApp> {
); );
} }
///share multiple images
_shareMultipleImages() async {
List<Asset> assetList = await MultiImagePicker.pickImages(maxImages: 5);
var imageList = List<String>();
for (var asset in assetList) {
imageList.add(await asset.filePath);
}
ShareExtend.shareMultiple(imageList, "image");
}
///share the documents file ///share the documents file
_shareApplicationDocumentsFile() async { _shareApplicationDocumentsFile() async {
Directory dir = await getApplicationDocumentsDirectory(); Directory dir = await getApplicationDocumentsDirectory();
File testFile = new File("${dir.path}/flutter/test.txt"); File testFile = File("${dir.path}/flutter/test.txt");
if (!await testFile.exists()) { if (!await testFile.exists()) {
await testFile.create(recursive: true); await testFile.create(recursive: true);
testFile.writeAsStringSync("test for share documents file"); testFile.writeAsStringSync("test for share documents file");
......
...@@ -21,6 +21,7 @@ dependencies: ...@@ -21,6 +21,7 @@ dependencies:
cupertino_icons: ^0.1.2 cupertino_icons: ^0.1.2
image_picker: image_picker:
path_provider: path_provider:
multi_image_picker: ^4.5.9
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* shareChannel = [FlutterMethodChannel FlutterMethodChannel* shareChannel = [FlutterMethodChannel
methodChannelWithName:@"share_extend" methodChannelWithName:@"com.zt.shareextend/share_extend"
binaryMessenger:[registrar messenger]]; binaryMessenger:[registrar messenger]];
[shareChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) { [shareChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
......
/// A flutter plugin to share text, image, file with system ui. /// A flutter plugin to share text, image, file with system ui.
/// It is compatible with both andorid and ios. /// It is compatible with both android and ios.
/// ///
/// ///
/// A open source authorized by zhouteng [https://github.com/zhouteng0217/ShareExtend](https://github.com/zhouteng0217/ShareExtend). /// A open source authorized by zhouteng [https://github.com/zhouteng0217/ShareExtend](https://github.com/zhouteng0217/ShareExtend).
...@@ -11,29 +11,43 @@ import 'dart:ui'; ...@@ -11,29 +11,43 @@ import 'dart:ui';
/// Plugin for summoning a platform share sheet. /// Plugin for summoning a platform share sheet.
class ShareExtend { class ShareExtend {
/// [MethodChannel] used to communicate with the platform side. /// [MethodChannel] used to communicate with the platform side.
static const MethodChannel _channel = const MethodChannel('share_extend'); static const MethodChannel _channel =
const MethodChannel('com.zt.shareextend/share_extend');
static Future<void> shareMultiple(List<String> list, String type,
{Rect sharePositionOrigin}) {
assert(list != null && list.isNotEmpty);
return _shareInner(list, type, sharePositionOrigin: sharePositionOrigin);
}
static Future<void> share(String text, String type,
{Rect sharePositionOrigin}) {
assert(text != null);
assert(text.isNotEmpty);
List<String> list = [text];
return _shareInner(list, type, sharePositionOrigin: sharePositionOrigin);
}
/// method to share with system ui /// method to share with system ui
/// It uses the ACTION_SEND Intent on Android and UIActivityViewController /// It uses the ACTION_SEND Intent on Android and UIActivityViewController
/// on iOS. /// on iOS.
/// type "text", "image" ,"file" /// [list] can be text or path list
/// [type] "text", "image" ,"file"
/// [sharePositionOrigin] only supports ios
/// ///
static Future<void> share(String text, String type, static Future<void> _shareInner(List<String> list, String type,
{Rect sharePositionOrigin}) { {Rect sharePositionOrigin}) {
assert(text != null); assert(list != null && list.isNotEmpty);
assert(text.isNotEmpty);
final Map<String, dynamic> params = <String, dynamic>{ final Map<String, dynamic> params = <String, dynamic>{
'text': text, 'list': list,
'type': type 'type': type
}; };
if (sharePositionOrigin != null) { if (sharePositionOrigin != null) {
params['originX'] = sharePositionOrigin.left; params['originX'] = sharePositionOrigin.left;
params['originY'] = sharePositionOrigin.top; params['originY'] = sharePositionOrigin.top;
params['originWidth'] = sharePositionOrigin.width; params['originWidth'] = sharePositionOrigin.width;
params['originHeight'] = sharePositionOrigin.height; params['originHeight'] = sharePositionOrigin.height;
} }
return _channel.invokeMethod('share', params); return _channel.invokeMethod('share', params);
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment