Skip to content

Commit

Permalink
将android 7.0中FileProvider获取url的方法集成到插件库中
Browse files Browse the repository at this point in the history
  • Loading branch information
zhouteng0217 committed Dec 17, 2018
1 parent 409afda commit 4eb8ee2
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 82 deletions.
16 changes: 15 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zt.shareextend">
package="com.zt.shareextend">

<application>

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.zt.shareextend.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_path" />
</provider>

</application>
</manifest>
123 changes: 64 additions & 59 deletions android/src/main/java/com/zt/shareextend/ShareExtendPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,74 +15,79 @@
import java.io.File;
import java.util.Map;

/** Plugin method host for presenting a share sheet via Intent */
/**
* Plugin method host for presenting a share sheet via Intent
*/
public class ShareExtendPlugin implements MethodChannel.MethodCallHandler {

private static final String CHANNEL = "share_extend";

public static void registerWith(Registrar registrar) {
MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL);
ShareExtendPlugin instance = new ShareExtendPlugin(registrar);
channel.setMethodCallHandler(instance);
}

private final Registrar mRegistrar;

private ShareExtendPlugin(Registrar registrar) {
this.mRegistrar = registrar;
}

@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("share")) {
if (!(call.arguments instanceof Map)) {
throw new IllegalArgumentException("Map argument expected");
}
// Android does not support showing the share sheet at a particular point on screen.
share((String) call.argument("text"),(String) call.argument("type"),(String) call.argument("authorities"));
result.success(null);
} else {
result.notImplemented();
private static final String authorities = "com.zt.shareextend.fileprovider";

private static final String CHANNEL = "share_extend";

public static void registerWith(Registrar registrar) {
MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL);
ShareExtendPlugin instance = new ShareExtendPlugin(registrar);
channel.setMethodCallHandler(instance);
}
}

private void share(String text, String type,String authorities) {
if (text == null || text.isEmpty()) {
throw new IllegalArgumentException("Non-empty text expected");
private final Registrar mRegistrar;

private ShareExtendPlugin(Registrar registrar) {
this.mRegistrar = registrar;
}

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);

if ("text".equals(type)) {
shareIntent.putExtra(Intent.EXTRA_TEXT, text);
shareIntent.setType("text/plain");
} else {
File f = new File(text);
Uri uri = getUriForFile(mRegistrar.context(), authorities,f);
if ("file".equals(type)) {
shareIntent.setType("application/*");
}
if ("image".equals(type)) {
shareIntent.setType("image/*");
}
shareIntent.putExtra(Intent.EXTRA_STREAM,uri);
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("share")) {
if (!(call.arguments instanceof Map)) {
throw new IllegalArgumentException("Map argument expected");
}
// Android does not support showing the share sheet at a particular point on screen.
share((String) call.argument("text"), (String) call.argument("type"));
result.success(null);
} else {
result.notImplemented();
}
}

Intent chooserIntent = Intent.createChooser(shareIntent, null /* dialog title optional */);
if (mRegistrar.activity() != null) {
mRegistrar.activity().startActivity(chooserIntent);
} else {
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mRegistrar.context().startActivity(chooserIntent);
private void share(String text, String type) {
if (text == null || text.isEmpty()) {
throw new IllegalArgumentException("Non-empty text expected");
}

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);

if ("text".equals(type)) {
shareIntent.putExtra(Intent.EXTRA_TEXT, text);
shareIntent.setType("text/plain");
} else {
File f = new File(text);
Uri uri = getUriForFile(mRegistrar.context(), f);
if ("file".equals(type)) {
shareIntent.setType("application/*");
}
if ("image".equals(type)) {
shareIntent.setType("image/*");
}
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
}

Intent chooserIntent = Intent.createChooser(shareIntent, null /* dialog title optional */);
if (mRegistrar.activity() != null) {
mRegistrar.activity().startActivity(chooserIntent);
} else {
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mRegistrar.context().startActivity(chooserIntent);
}
}
}

public static Uri getUriForFile(Context context, String authories, File file) {
if (Build.VERSION.SDK_INT >= 24) {
return FileProvider.getUriForFile(context, authories, file);
} else {
return Uri.fromFile(file);

public static Uri getUriForFile(Context context, File file) {
if (Build.VERSION.SDK_INT >= 24) {
return FileProvider.getUriForFile(context, authorities, file);
} else {
return Uri.fromFile(file);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="external_cache"
path="" />
<root-path
name="root_path"
path="/" />
</paths>
</resources>
11 changes: 1 addition & 10 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
Expand Down Expand Up @@ -36,15 +37,5 @@
</intent-filter>
</activity>

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.zt.shareextend.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_path" />
</provider>

</application>
</manifest>
60 changes: 54 additions & 6 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:io';

import 'package:share_extend/share_extend.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission/permission.dart';
import 'package:path_provider/path_provider.dart';

void main() => runApp(new MyApp());

Expand All @@ -12,9 +14,6 @@ class MyApp extends StatefulWidget {
}

class _MyAppState extends State<MyApp> {
///define in android project AndroidManifest.xml for FileProvider
static const String authorities = "com.zt.shareextend.fileprovider";

@override
void initState() {
super.initState();
Expand All @@ -32,29 +31,78 @@ class _MyAppState extends State<MyApp> {
children: <Widget>[
new RaisedButton(
onPressed: () {
ShareExtend.share("share text", "text", authorities);
ShareExtend.share("share text", "text");
},
child: new Text("share text"),
),
new RaisedButton(
onPressed: () async {
File f =
await ImagePicker.pickImage(source: ImageSource.gallery);
ShareExtend.share(f.path, "image", authorities);
ShareExtend.share(f.path, "image");
},
child: new Text("share image"),
),
new RaisedButton(
onPressed: () async {
File f =
await ImagePicker.pickImage(source: ImageSource.gallery);
ShareExtend.share(f.path, "file", authorities);
ShareExtend.share(f.path, "file");
},
child: new Text("share file"),
),
new RaisedButton(
onPressed: () {
if (Platform.isAndroid) {
_shareFileWithPerm();
}
},
child: new Text("share android external storage file"),
),
],
)),
),
);
}

/// share the external storage file ,first check the permission
_shareFileWithPerm() async {
if (await _checkPermission()) {
_shareFile();
} else {
var result = await _requestPermission();

/// to ask for permission
if (result == PermissionStatus.allow) {
_shareFile();
}
}
}

/// create a test file for the share example
_shareFile() async {
String filePath = await _createTestFileToShare();
ShareExtend.share(filePath, "file");
}

///create a test file to share
_createTestFileToShare() async {
Directory storageDir = await getExternalStorageDirectory();
File testFile = new File("${storageDir.path}/flutter/test.txt");
if (!await testFile.exists()) {
await testFile.create(recursive: true);
}
testFile.writeAsStringSync("test for share");
return testFile.path;
}

_checkPermission() async {
List<Permissions> perms =
await Permission.getPermissionStatus([PermissionName.Storage]);
return perms[0].permissionStatus == PermissionStatus.allow;
}

_requestPermission() async {
return await Permission.requestSinglePermission(PermissionName.Storage);
}
}
2 changes: 2 additions & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
image_picker: ^0.4.10
path_provider: ^0.4.1
permission: ^0.1.0


dev_dependencies:
Expand Down
5 changes: 2 additions & 3 deletions lib/share_extend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ class ShareExtend {
/// on iOS.
/// type "text", "image" ,"file"
///
static Future<void> share(String text, String type, String authorities,
static Future<void> share(String text, String type,
{Rect sharePositionOrigin}) {
assert(text != null);
assert(text.isNotEmpty);
final Map<String, dynamic> params = <String, dynamic>{
'text': text,
'type': type,
'authorities': authorities
'type': type
};

if (sharePositionOrigin != null) {
Expand Down

0 comments on commit 4eb8ee2

Please sign in to comment.