Commit 1c5d0220 authored by zhouteng's avatar zhouteng

update project to support android embedding v2 api

parent b24c80ad
package com.zt.shareextend;
import androidx.annotation.NonNull;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/**
* Created by zhouteng on 2020/6/27
*/
public class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
private static final String METHOD_SHARE = "share";
private Share share;
public MethodCallHandlerImpl(Share share) {
this.share = share;
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
if (METHOD_SHARE.equals(call.method)) {
if (!(call.arguments instanceof Map)) {
throw new IllegalArgumentException("Map argument expected");
}
share.share(call);
result.success(null);
} else {
result.notImplemented();
}
}
}
package com.zt.shareextend;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import io.flutter.plugin.common.MethodCall;
/**
* Created by zhouteng on 2020/6/27
* <p>
* Handles share action
*/
public class Share {
private static final int CODE_ASK_PERMISSION = 100;
private Context context;
private MethodCall call;
public Share(Context context) {
this.context = context;
}
void share() {
share(call);
}
void share(MethodCall call) {
if (call == null) {
return;
}
this.call = call;
List<String> list = call.argument("list");
String type = call.argument("type");
String sharePanelTitle = call.argument("sharePanelTitle");
String subject = call.argument("subject");
String extraText = call.argument("extraText");
if (list == null || list.isEmpty()) {
throw new IllegalArgumentException("Non-empty list expected");
}
ArrayList<Uri> uriList = new ArrayList<>();
Intent shareIntent = new Intent();
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
if ("text".equals(type)) {
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, list.get(0));
shareIntent.setType("text/plain");
} else {
if (ShareUtils.shouldRequestPermission(list)) {
if (!checkPermission()) {
requestPermission();
return;
}
}
shareIntent.putExtra(Intent.EXTRA_TEXT, extraText);
for (String path : list) {
File f = new File(path);
Uri uri = ShareUtils.getUriForFile(context, f);
uriList.add(uri);
}
if ("image".equals(type)) {
shareIntent.setType("image/*");
} else if ("video".equals(type)) {
shareIntent.setType("video/*");
} else {
shareIntent.setType("application/*");
}
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, sharePanelTitle, uriList);
}
private void startChooserActivity(Intent shareIntent, String sharePanelTitle, ArrayList<Uri> uriList) {
Intent chooserIntent = Intent.createChooser(shareIntent, sharePanelTitle);
ShareUtils.grantUriPermission(context, uriList, chooserIntent);
if (context instanceof Activity) {
context.startActivity(chooserIntent);
} else {
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(chooserIntent);
}
}
private boolean checkPermission() {
return ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
if (!(context instanceof Activity)) {
return;
}
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_ASK_PERMISSION);
}
}
package com.zt.shareextend;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import io.flutter.plugin.common.MethodCall;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar;
......@@ -23,125 +16,78 @@ import io.flutter.plugin.common.PluginRegistry.Registrar;
/**
* Plugin method host for presenting a share sheet via Intent
*/
public class ShareExtendPlugin implements MethodChannel.MethodCallHandler, PluginRegistry.RequestPermissionsResultListener {
public class ShareExtendPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.RequestPermissionsResultListener {
/// the authorities for FileProvider
private static final int CODE_ASK_PERMISSION = 100;
private static final String CHANNEL = "com.zt.shareextend/share_extend";
private final Registrar mRegistrar;
private List<String> list;
private String type;
private String sharePanelTitle;
private String subject;
private String extraText;
private FlutterPluginBinding pluginBinding;
private ActivityPluginBinding activityBinding;
private MethodChannel methodChannel;
private MethodCallHandlerImpl callHandler;
private Share share;
public static void registerWith(Registrar registrar) {
MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL);
final ShareExtendPlugin instance = new ShareExtendPlugin(registrar);
registrar.addRequestPermissionsResultListener(instance);
channel.setMethodCallHandler(instance);
ShareExtendPlugin plugin = new ShareExtendPlugin();
plugin.setUpChannel(registrar.context(), registrar.messenger(), registrar, null);
}
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
pluginBinding = flutterPluginBinding;
}
private ShareExtendPlugin(Registrar registrar) {
this.mRegistrar = registrar;
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
pluginBinding = null;
}
@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.
list = call.argument("list");
type = call.argument("type");
sharePanelTitle = call.argument("sharePanelTitle");
subject = call.argument("subject");
extraText = call.argument("extraText");
share(list, type, sharePanelTitle, subject, extraText);
result.success(null);
} else {
result.notImplemented();
}
public void onAttachedToActivity(@NonNull ActivityPluginBinding activityPluginBinding) {
activityBinding = activityPluginBinding;
setUpChannel(activityBinding.getActivity(), pluginBinding.getBinaryMessenger(), null, activityBinding);
}
private void share(List<String> list, String type, String sharePanelTitle, String subject, String extraText) {
ArrayList<Uri> uriList = new ArrayList<>();;
@Override
public void onDetachedFromActivityForConfigChanges() {
onDetachedFromActivity();
}
if (list == null || list.isEmpty()) {
throw new IllegalArgumentException("Non-empty list expected");
}
Intent shareIntent = new Intent();
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
if ("text".equals(type)) {
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, list.get(0));
shareIntent.setType("text/plain");
} else {
if (ShareUtils.shouldRequestPermission(list)) {
if (!checkPermission()) {
requestPermission();
return;
}
}
shareIntent.putExtra(Intent.EXTRA_TEXT, extraText);
for (String path : list) {
File f = new File(path);
Uri uri = ShareUtils.getUriForFile(getContext(), f);
uriList.add(uri);
}
if ("image".equals(type)) {
shareIntent.setType("image/*");
} else if ("video".equals(type)) {
shareIntent.setType("video/*");
} else {
shareIntent.setType("application/*");
}
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, sharePanelTitle, uriList);
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding activityPluginBinding) {
onAttachedToActivity(activityPluginBinding);
}
private Context getContext() {
return mRegistrar.activity() != null ? mRegistrar.activity() : mRegistrar.context();
@Override
public void onDetachedFromActivity() {
tearDown();
}
private void startChooserActivity(Intent shareIntent, String sharePanelTitle, ArrayList<Uri> uriList) {
Intent chooserIntent = Intent.createChooser(shareIntent, sharePanelTitle);
ShareUtils.grantUriPermission(getContext(), uriList, chooserIntent);
if (mRegistrar.activity() != null) {
mRegistrar.activity().startActivity(chooserIntent);
private void setUpChannel(Context context, BinaryMessenger messenger,Registrar registrar, ActivityPluginBinding activityBinding) {
methodChannel = new MethodChannel(messenger, CHANNEL);
share = new Share(context);
callHandler = new MethodCallHandlerImpl(share);
methodChannel.setMethodCallHandler(callHandler);
if (registrar != null) {
registrar.addRequestPermissionsResultListener(this);
} else {
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mRegistrar.context().startActivity(chooserIntent);
activityBinding.addRequestPermissionsResultListener(this);
}
}
private boolean checkPermission() {
return ContextCompat.checkSelfPermission(mRegistrar.context(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(mRegistrar.activity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_ASK_PERMISSION);
private void tearDown() {
activityBinding.removeRequestPermissionsResultListener(this);
activityBinding = null;
methodChannel.setMethodCallHandler(null);
methodChannel = null;
}
@Override
public boolean onRequestPermissionsResult(int requestCode, String[] perms, int[] grantResults) {
if (requestCode == CODE_ASK_PERMISSION && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
share(list, type, sharePanelTitle, subject, extraText);
share.share();
}
return false;
}
......
......@@ -20,25 +20,40 @@
android:name="io.flutter.app.FlutterApplication"
android:label="share_extend_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:name="io.flutter.embedding.android.FlutterActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- used for v1 api -->
<activity
android:name=".EmbeddingV1Activity"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
</activity>
<meta-data android:name="flutterEmbedding" android:value="2"/>
</application>
</manifest>
package com.zt.shareextendexample;
import android.os.Bundle;
import com.vitanov.multiimagepicker.MultiImagePickerPlugin;
import com.zt.shareextend.ShareExtendPlugin;
import io.flutter.app.FlutterActivity;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin;
import io.flutter.plugins.imagepicker.ImagePickerPlugin;
import io.flutter.plugins.pathprovider.PathProviderPlugin;
public class EmbeddingV1Activity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ShareExtendPlugin.registerWith(registrarFor("com.zt.shareextend.ShareExtendPlugin"));
ImagePickerPlugin.registerWith(registrarFor("io.flutter.plugins.imagepicker.ImagePickerPlugin"));
MultiImagePickerPlugin.registerWith(registrarFor("com.vitanov.multiimagepicker.MultiImagePickerPlugin"));
PathProviderPlugin.registerWith(registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"));
FlutterAndroidLifecyclePlugin.registerWith(registrarFor("io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin"));
}
}
package com.zt.shareextendexample;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
......@@ -18,9 +18,12 @@ dependencies:
# The following section is specific to Flutter.
flutter:
plugin:
androidPackage: com.zt.shareextend
pluginClass: ShareExtendPlugin
iosPrefix: FLT
platforms:
android:
package: com.zt.shareextend
pluginClass: ShareExtendPlugin
ios:
pluginClass: FLTShareExtendPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
......
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