diff --git a/.gitignore b/.gitignore index 60f9d69..765dbc6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.idea +publish.sh .DS_Store .dart_tool/ diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml deleted file mode 100644 index 6b36ee2..0000000 --- a/.idea/libraries/Dart_SDK.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Flutter_for_Android.xml b/.idea/libraries/Flutter_for_Android.xml deleted file mode 100644 index 3ff4bef..0000000 --- a/.idea/libraries/Flutter_for_Android.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 5a71f78..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/.idea/runConfigurations/example_lib_main_dart.xml b/.idea/runConfigurations/example_lib_main_dart.xml deleted file mode 100644 index 5fd9159..0000000 --- a/.idea/runConfigurations/example_lib_main_dart.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 36c8ba0..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CHANGELOG.md b/CHANGELOG.md index 41cc7d8..67b5cb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ -## 0.0.1 +## 0.1.0 * TODO: Describe initial release. diff --git a/README.md b/README.md index c3ef16e..ce70fd9 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,3 @@ -# mop +# 凡泰极客小程序 Flutter 插件 -A new flutter plugin project. - -## Getting Started - -This project is a starting point for a Flutter -[plug-in package](https://flutter.dev/developing-packages/), -a specialized package that includes platform-specific implementation code for -Android and/or iOS. - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +本插件提供在 Flutter 运行环境中运行小程序能力。 diff --git a/android/build.gradle b/android/build.gradle index 7f04a8a..5231008 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,3 +1,10 @@ + +apply plugin: 'com.android.library' + +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-android-extensions' + group 'com.finogeeks.mop' version '1.0' @@ -5,10 +12,21 @@ buildscript { repositories { google() jcenter() + maven { + url "https://gradle.finogeeks.club/repository/applet/" + credentials { + username "applet" + password "123321" + } + } + maven { url "https://jitpack.io" } + } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.5.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61" + } } @@ -16,19 +34,49 @@ rootProject.allprojects { repositories { google() jcenter() + maven { + url "https://gradle.finogeeks.club/repository/applet/" + credentials { + username "applet" + password "123321" + } + } + maven { url "https://jitpack.io" } + } } -apply plugin: 'com.android.library' android { compileSdkVersion 28 defaultConfig { - minSdkVersion 16 - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + minSdkVersion 21 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } lintOptions { disable 'InvalidPackage' } } + +kapt { + arguments { + arg("moduleName", project.getName()) + } +} +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.finogeeks.lib:finapplet:2.0.77' + +} diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 019065d..d757f3d 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/android/proguard-android.txt b/android/proguard-android.txt new file mode 100644 index 0000000..e69de29 diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro new file mode 100644 index 0000000..4194f7b --- /dev/null +++ b/android/proguard-rules.pro @@ -0,0 +1,5 @@ +-keep class com.finogeeks.** {*;} + +# tbs +-keep class com.tencent.smtt.** {*;} +-keep class com.tencent.tbs.** {*;} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/MopEventStream.java b/android/src/main/java/com/finogeeks/mop/MopEventStream.java new file mode 100644 index 0000000..baed58d --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/MopEventStream.java @@ -0,0 +1,29 @@ +package com.finogeeks.mop; + +import java.util.HashMap; +import java.util.Map; + +import io.flutter.plugin.common.EventChannel; + + +public class MopEventStream implements EventChannel.StreamHandler { + EventChannel.EventSink mEventSlink; + @Override + public void onListen(Object o, EventChannel.EventSink eventSink) { + mEventSlink = eventSink; + } + + @Override + public void onCancel(Object o) { + mEventSlink = null; + } + public void send(String channel,String event,Object body) { + if (mEventSlink != null) { + Map map = new HashMap<>(); + map.put("channel",channel); + map.put("event",event); + map.put("body",body); + mEventSlink.success(map); + } + } +} diff --git a/android/src/main/java/com/finogeeks/mop/MopPlugin.java b/android/src/main/java/com/finogeeks/mop/MopPlugin.java index a2c623f..9ec335d 100644 --- a/android/src/main/java/com/finogeeks/mop/MopPlugin.java +++ b/android/src/main/java/com/finogeeks/mop/MopPlugin.java @@ -1,25 +1,99 @@ package com.finogeeks.mop; +import android.content.Intent; +import android.util.Log; + +import com.finogeeks.mop.interfaces.Event; +import com.finogeeks.mop.interfaces.FlutterInterface; +import com.finogeeks.mop.interfaces.ICallback; +import com.finogeeks.mop.service.MopPluginService; + +import java.util.HashMap; +import java.util.Map; + +import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry.Registrar; /** MopPlugin */ public class MopPlugin implements MethodCallHandler { - /** Plugin registration. */ + private static final String LOG_TAG = MopPlugin.class.getSimpleName(); + + private static final String CHANNEL = "mop"; + private PluginRegistry.Registrar registrar; + private FlutterInterface flutterInterface; + private MopPluginDelegate delegate; + + + + + /** + * Plugin registration. + */ public static void registerWith(Registrar registrar) { - final MethodChannel channel = new MethodChannel(registrar.messenger(), "mop"); - channel.setMethodCallHandler(new MopPlugin()); + final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL); + final MopPluginDelegate delegate = new MopPluginDelegate(registrar.activity()); + final MopPlugin instance = new MopPlugin(registrar,delegate); + channel.setMethodCallHandler(instance); + final EventChannel eventChannel=new EventChannel(registrar.messenger(),"plugins.mop.finogeeks.com/mop_event"); + MopEventStream mopEventStream = new MopEventStream(); + eventChannel.setStreamHandler(mopEventStream); + MopPluginService.getInstance().initialize(registrar.activity(),mopEventStream); + + } + + MopPlugin(PluginRegistry.Registrar registrar,MopPluginDelegate delegate) { + this.registrar = registrar; + this.flutterInterface = new FlutterInterface(); + this.delegate = delegate; } @Override - public void onMethodCall(MethodCall call, Result result) { - if (call.method.equals("getPlatformVersion")) { - result.success("Android " + android.os.Build.VERSION.RELEASE); - } else { - result.notImplemented(); - } + public void onMethodCall(MethodCall call, final Result result) { + registrar.addActivityResultListener(delegate); + ICallback callback = new ICallback() { + @Override + public void onSuccess(Object data) { + Map obj = new HashMap(); + + obj.put("success",true); + if (data != null) + obj.put("data",data); + obj.put("retMsg","ok"); + result.success(obj); + } + + @Override + public void onFail(Object error) { + Map obj = new HashMap(); + obj.put("success",false); + obj.put("retMsg",error==null?"":error); + result.success(obj); + } + + @Override + public void onCancel(Object cancel) { + result.notImplemented(); + } + + @Override + public void startActivityForResult(Intent intent, int requestCode) { + + } + }; + Log.d(LOG_TAG,"mopplugin: invoke " + call.method); + Event event= new Event(call.method,call.arguments,callback); + delegate.setEvent(event); + this.flutterInterface.invokeHandler(event); +// if (call.method.equals("getPlatformVersion")) { +// result.success("Android " + android.os.Build.VERSION.RELEASE); +// } else { +// result.notImplemented(); +// } } + } diff --git a/android/src/main/java/com/finogeeks/mop/MopPluginDelegate.java b/android/src/main/java/com/finogeeks/mop/MopPluginDelegate.java new file mode 100644 index 0000000..23ec9a3 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/MopPluginDelegate.java @@ -0,0 +1,40 @@ +package com.finogeeks.mop; + +import android.app.Activity; +import android.content.Intent; + +import com.finogeeks.mop.constants.Constants; +import com.finogeeks.mop.interfaces.Event; +import com.finogeeks.mop.service.MopPluginService; + +import io.flutter.plugin.common.PluginRegistry; + + +public class MopPluginDelegate implements PluginRegistry.ActivityResultListener { + + private Event mEvent; + private final Activity activity; + + public Event getEvent() { + return mEvent; + } + + public void setEvent(Event event) { + this.mEvent = event; + } + + public MopPluginDelegate(final Activity activity) { + this.activity = activity; + + } + @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == Constants.REQUEST_CODE_CHOOSE + || requestCode == Constants.REQUEST_CODE_LOCATION_CHOOSE + ) { + MopPluginService.getInstance().getApisManager().getApiInstance(mEvent).onActivityResult(requestCode, resultCode, data, mEvent.getCallback()); + } + return true; + } + +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/api/AbsApi.java b/android/src/main/java/com/finogeeks/mop/api/AbsApi.java new file mode 100644 index 0000000..bbd09d2 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/AbsApi.java @@ -0,0 +1,36 @@ +package com.finogeeks.mop.api; + +import android.content.Intent; + +import com.finogeeks.mop.interfaces.IApi; +import com.finogeeks.mop.interfaces.ICallback; + +public abstract class AbsApi implements IApi { + + @Override + public void onCreate() { + + } + + @Override + public void onDestroy() { + + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data, ICallback callback) { + + } + @Override + public void onNewIntent(Intent intent) { + + } + @Override + public void onResume() { + + } + @Override + public void onPause() { + + } +} diff --git a/android/src/main/java/com/finogeeks/mop/api/ApisManager.java b/android/src/main/java/com/finogeeks/mop/api/ApisManager.java new file mode 100644 index 0000000..85637fc --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/ApisManager.java @@ -0,0 +1,76 @@ +package com.finogeeks.mop.api; + +import android.app.Activity; +import android.text.TextUtils; + +import com.finogeeks.mop.api.mop.AppletModule; +import com.finogeeks.mop.api.mop.BaseModule; +import com.finogeeks.mop.interfaces.Event; +import com.finogeeks.mop.interfaces.IApi; + +import java.util.HashMap; +import java.util.Map; + +public class ApisManager { + + + private final static String TAG = ApisManager.class.getSimpleName(); + + public static final int SUCCESS = 0x10; + public static final int FAIL = 0x11; + public static final int CANCEL = 0x12; + public static final int PENDING = 0x13; + + private final IApi EMPTY_API = new EmptyApi(); + private final Map APIS = new HashMap<>(); + private Activity mActivity; + + public ApisManager(Activity activity) { + mActivity = activity; + initSdkApi(activity); + } + /** + * api功能调用 + * + * @param event 封装了api名称,参数及回调函数id的对象 + */ + public IApi getApiInstance(Event event) { + IApi api = APIS.get(event.getName()); + if (api != null) { + return api; + } + return null; + + } + /** + * api功能调用 + * + * @param event 封装了api名称,参数及回调函数id的对象 + */ + public void invoke(Event event) { + IApi api = APIS.get(event.getName()); + if (api != null) { + api.invoke(event.getName(), event.getParam(), event.getCallback()); + return; + } + + } + + private void initSdkApi(Activity activity) { + add(new BaseModule(activity)); + add(new AppletModule(activity)); + + } + + private void add(IApi api) { + if (api != null && api.apis() != null && api.apis().length > 0) { + String[] apiNames = api.apis(); + for (String name : apiNames) { + if (!TextUtils.isEmpty(name)) { + APIS.put(name, api); + } + } + } + } + +} diff --git a/android/src/main/java/com/finogeeks/mop/api/BaseApi.java b/android/src/main/java/com/finogeeks/mop/api/BaseApi.java new file mode 100644 index 0000000..837f51a --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/BaseApi.java @@ -0,0 +1,23 @@ +package com.finogeeks.mop.api; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +public abstract class BaseApi extends AbsApi { + + + protected static final String TAG = "InnerApi"; + + protected static final Handler HANDLER = new Handler(Looper.getMainLooper()); + + private Context mContext; + + public BaseApi(Context context) { + mContext = context; + } + + public Context getContext() { + return mContext; + } +} diff --git a/android/src/main/java/com/finogeeks/mop/api/EmptyApi.java b/android/src/main/java/com/finogeeks/mop/api/EmptyApi.java new file mode 100644 index 0000000..acf1504 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/EmptyApi.java @@ -0,0 +1,49 @@ +package com.finogeeks.mop.api; + +import android.content.Intent; + +import com.finogeeks.mop.interfaces.IApi; +import com.finogeeks.mop.interfaces.ICallback; + +import java.util.Map; + +public class EmptyApi implements IApi { + + + @Override + public void onCreate() { + + } + + @Override + public void onDestroy() { + + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data, ICallback callback) { + + } + @Override + public void onNewIntent(Intent data) { + + } + @Override + public void onResume() { + + } + @Override + public void onPause() { + + } + + @Override + public String[] apis() { + return null; + } + + @Override + public void invoke(String event, Map param, ICallback callback) { + + } +} diff --git a/android/src/main/java/com/finogeeks/mop/api/mop/AppletModule.java b/android/src/main/java/com/finogeeks/mop/api/mop/AppletModule.java new file mode 100644 index 0000000..c2d099e --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/mop/AppletModule.java @@ -0,0 +1,49 @@ +package com.finogeeks.mop.api.mop; + +import android.content.Context; + +import com.finogeeks.lib.applet.client.FinAppClient; +import com.finogeeks.mop.api.BaseApi; +import com.finogeeks.mop.interfaces.ICallback; + +import java.util.HashMap; +import java.util.Map; + +public class AppletModule extends BaseApi { + private final static String TAG = AppletModule.class.getSimpleName(); + private Context mContext; + public AppletModule(Context context) { + super(context); + mContext = context; + } + + @Override + public void onCreate() { + super.onCreate(); + + } + @Override + public String[] apis() { + return new String[]{"openApplet"}; + } + + @Override + public void invoke(String event, Map param, ICallback callback) { + if (param.get("appId") == null) { + callback.onFail(new HashMap(){ + { + put("info","appId不能为空"); + } + }); + return; + } + String appId = String.valueOf(param.get("appId")); + Map params = (Map)param.get("params"); + if (params == null) { + FinAppClient.INSTANCE.getAppletApiManager().startApplet(mContext, appId); + } else { + FinAppClient.INSTANCE.getAppletApiManager().startApplet(mContext, appId, params); + } + callback.onSuccess(new HashMap()); + } +} diff --git a/android/src/main/java/com/finogeeks/mop/api/mop/BaseModule.java b/android/src/main/java/com/finogeeks/mop/api/mop/BaseModule.java new file mode 100644 index 0000000..989190c --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/api/mop/BaseModule.java @@ -0,0 +1,85 @@ +package com.finogeeks.mop.api.mop; + +import android.content.Context; +import android.widget.Toast; + +import com.finogeeks.lib.applet.client.FinAppClient; +import com.finogeeks.lib.applet.client.FinAppConfig; +import com.finogeeks.lib.applet.interfaces.FinCallback; +import com.finogeeks.mop.api.BaseApi; +import com.finogeeks.mop.interfaces.ICallback; +import com.finogeeks.mop.service.MopPluginService; + +import java.util.HashMap; +import java.util.Map; + +public class BaseModule extends BaseApi { + private final static String TAG = BaseModule.class.getSimpleName(); + + public BaseModule(Context context) { + super(context); + } + + @Override + public void onCreate() { + super.onCreate(); + + } + @Override + public String[] apis() { + return new String[]{"initialize"}; + } + + @Override + public void invoke(String event, Map param, final ICallback callback) { + + if (FinAppClient.INSTANCE.isFinAppProcess(super.getContext())) { + // 小程序进程不执行任何初始化操作 + return; + } + String appkey = String.valueOf(param.get("appkey")); + String secret = String.valueOf(param.get("secret")); + String apiServer = "https://mp.finogeeks.com"; + String apiPrefix = "/api/v1/mop/"; + if (param.get("apiServer") != null) { + apiServer = String.valueOf(param.get("apiServer")); + } + if (param.get("apiPrefix") != null) { + apiPrefix = String.valueOf(param.get("apiPrefix")); + if (!apiPrefix.endsWith("/")) { + apiPrefix = apiPrefix + "/"; + } + } + FinAppConfig config = new FinAppConfig.Builder() + .setAppKey(appkey) + .setAppSecret(secret) + .setApiUrl(apiServer) + .setApiPrefix(apiPrefix) + .setGlideWithJWT(false) + .build(); + // SDK初始化结果回调,用于接收SDK初始化状态 + FinCallback cb = new FinCallback() { + @Override + public void onSuccess(Object result) { + // SDK初始化成功 + callback.onSuccess(null); + } + + @Override + public void onError(int code, String error) { + // SDK初始化失败 + callback.onFail(null); +// Toast.makeText(MopPluginService.getInstance().getContext(), "SDK初始化失败", Toast.LENGTH_SHORT).show(); + } + + @Override + public void onProgress(int status, String error) { + + } + }; + FinAppClient.INSTANCE.init(MopPluginService.getInstance().getActivity().getApplication(), config, cb); + + + + } +} diff --git a/android/src/main/java/com/finogeeks/mop/constants/Constants.java b/android/src/main/java/com/finogeeks/mop/constants/Constants.java new file mode 100644 index 0000000..6faca61 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/constants/Constants.java @@ -0,0 +1,11 @@ +package com.finogeeks.mop.constants; + +/** + * 全局常量池 + */ +public class Constants { + public static final int REQUEST_CODE_CHOOSE = 0x1000000; + public static final int REQUEST_CODE_LOCATION_CHOOSE = 0x1000001; + public static final int REQUEST_CODE_LOCATION_PREVIEW = 0x1000002; + public static final int REQUEST_CODE_SELECT_DOCUMENT = 0x1000003; +} diff --git a/android/src/main/java/com/finogeeks/mop/interfaces/Event.java b/android/src/main/java/com/finogeeks/mop/interfaces/Event.java new file mode 100644 index 0000000..a4eff61 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/interfaces/Event.java @@ -0,0 +1,35 @@ +package com.finogeeks.mop.interfaces; + + +import java.util.Map; + +public final class Event { + + private String name; + private Object param; + private ICallback callback; + + + public Event(String name, Object param, ICallback callback) { + this.name = name; + this.param = param; + this.callback = callback; + } + + public String getName() { + return name; + } + + public Map getParam() { + if (param instanceof Map) { + + return (Map)param; + } + return null; + } + + public ICallback getCallback() { + return callback; + } + +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/interfaces/FlutterInterface.java b/android/src/main/java/com/finogeeks/mop/interfaces/FlutterInterface.java new file mode 100644 index 0000000..7918d1d --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/interfaces/FlutterInterface.java @@ -0,0 +1,23 @@ +package com.finogeeks.mop.interfaces; + +import android.os.Handler; +import android.os.Looper; + +import com.finogeeks.mop.service.MopPluginService; + + +public class FlutterInterface { + private static final String TAG = FlutterInterface.class.getSimpleName(); + + private Handler mHandler = new Handler(Looper.getMainLooper()); + + public void invokeHandler(final Event event) { + + mHandler.post(new Runnable() { + @Override + public void run() { + MopPluginService.getInstance().getApisManager().invoke(event); + } + }); + } +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/interfaces/IApi.java b/android/src/main/java/com/finogeeks/mop/interfaces/IApi.java new file mode 100644 index 0000000..60c9c98 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/interfaces/IApi.java @@ -0,0 +1,23 @@ +package com.finogeeks.mop.interfaces; + +import java.util.Map; + +/** + * Api接口,实现相应功能的Api需实现此接口 + */ +public interface IApi extends ILifecycle { + + /** + * @return 支持可调用的api名称的数组 + */ + String[] apis(); + + /** + * 接收到对应的api调用时,会调用此方法,在此方法中处理api调用的功能逻辑 + * + * @param event 事件名称,即api名称 + * @param param 参数 + * @param callback 回调接口 + */ + void invoke(String event, Map param, ICallback callback); +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/interfaces/ICallback.java b/android/src/main/java/com/finogeeks/mop/interfaces/ICallback.java new file mode 100644 index 0000000..26bdc63 --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/interfaces/ICallback.java @@ -0,0 +1,35 @@ +package com.finogeeks.mop.interfaces; + +import android.content.Intent; + +/** + * Api回调接口 + */ +public interface ICallback { + + /** + * Api调用成功 + * + * @param data Api调用返回的结果 + */ + void onSuccess(T data); + + /** + * Api调用失败 + */ + void onFail(T error); + + /** + * Api调用取消 + */ + void onCancel(T cancel); + + /** + * 回调{@link android.app.Activity#startActivityForResult(Intent, int)}方法 + * + * @param intent + * @param requestCode + */ + void startActivityForResult(Intent intent, int requestCode); + +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/interfaces/ILifecycle.java b/android/src/main/java/com/finogeeks/mop/interfaces/ILifecycle.java new file mode 100644 index 0000000..26afadd --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/interfaces/ILifecycle.java @@ -0,0 +1,39 @@ +package com.finogeeks.mop.interfaces; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +/** + * 绑定{@link Activity}生命周期的回调接口 + */ +public interface ILifecycle { + + /** + * 当{@link Activity#onCreate(Bundle)}方法调用时回调. + */ + void onCreate(); + + /** + * 当{@link Activity#onDestroy()}方法调用时回调. + */ + void onDestroy(); + + /** + * 当{@link Activity#onActivityResult(int, int, Intent)}方法调用时回调. + */ + void onActivityResult(int requestCode, int resultCode, Intent data, ICallback callback); + + /** + * 当{@link Activity#onNewIntent(Intent)}方法调用时回调. + */ + void onNewIntent(Intent intent); + /** + * 当{@link Activity#onResume()}方法调用时回调. + */ + void onResume(); + /** + * 当{@link Activity#onResume()}方法调用时回调. + */ + void onPause(); +} \ No newline at end of file diff --git a/android/src/main/java/com/finogeeks/mop/service/MopPluginService.java b/android/src/main/java/com/finogeeks/mop/service/MopPluginService.java new file mode 100644 index 0000000..ddd532c --- /dev/null +++ b/android/src/main/java/com/finogeeks/mop/service/MopPluginService.java @@ -0,0 +1,51 @@ +package com.finogeeks.mop.service; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; + +import com.finogeeks.mop.MopEventStream; +import com.finogeeks.mop.api.ApisManager; + +public class MopPluginService { + private final static String TAG = MopPluginService.class.getSimpleName(); + private static volatile MopPluginService _instance = null; + + private ApisManager apisManager; + private MopEventStream mopEventStream; + + + private Context mContext; + private Activity mActivity; + + MopPluginService() { + } + + public static MopPluginService getInstance() { + if (_instance == null) { + synchronized (MopPluginService.class) { + if (_instance == null) { + _instance = new MopPluginService(); + } + } + } + return _instance; + } + + public ApisManager getApisManager() { return this.apisManager;} + public MopEventStream getMopEventStream() {return this.mopEventStream;} + public void initialize(Activity activity, MopEventStream mopEventStream) { + this.mopEventStream = mopEventStream; + this.mContext = activity.getApplicationContext(); + this.apisManager = new ApisManager(activity); + this.mActivity = activity; + + + } + public Context getContext() { + return mContext; + } + public Activity getActivity() { + return mActivity; + } +} diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 13f624e..9e3d04e 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -33,12 +33,12 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.finogeeks.mop_example" - minSdkVersion 16 + applicationId "com.finogeeks.mopexample" + minSdkVersion 21 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -56,6 +56,6 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'androidx.test:runner:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' } diff --git a/example/android/app/src/debug/gen/com/finogeeks/mop_example/Manifest.java b/example/android/app/src/debug/gen/com/finogeeks/mop_example/Manifest.java new file mode 100644 index 0000000..59184ce --- /dev/null +++ b/example/android/app/src/debug/gen/com/finogeeks/mop_example/Manifest.java @@ -0,0 +1,7 @@ +/*___Generated_by_IDEA___*/ + +package com.finogeeks.mop_example; + +/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ +public final class Manifest { +} \ No newline at end of file diff --git a/example/android/app/src/debug/gen/com/finogeeks/mop_example/R.java b/example/android/app/src/debug/gen/com/finogeeks/mop_example/R.java new file mode 100644 index 0000000..928e6be --- /dev/null +++ b/example/android/app/src/debug/gen/com/finogeeks/mop_example/R.java @@ -0,0 +1,7 @@ +/*___Generated_by_IDEA___*/ + +package com.finogeeks.mop_example; + +/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ +public final class R { +} \ No newline at end of file diff --git a/example/android/app/src/main/java/com/finogeeks/mop_example/MainActivity.java b/example/android/app/src/main/java/com/finogeeks/mop_example/MainActivity.java index f7a1eee..55673ec 100644 --- a/example/android/app/src/main/java/com/finogeeks/mop_example/MainActivity.java +++ b/example/android/app/src/main/java/com/finogeeks/mop_example/MainActivity.java @@ -1,6 +1,7 @@ package com.finogeeks.mop_example; import android.os.Bundle; + import io.flutter.app.FlutterActivity; import io.flutter.plugins.GeneratedPluginRegistrant; @@ -9,5 +10,7 @@ public class MainActivity extends FlutterActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); + + } } diff --git a/example/android/build.gradle b/example/android/build.gradle index bb8a303..9957ae3 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,3 +1,4 @@ + buildscript { repositories { google() @@ -5,7 +6,8 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.5.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61" } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 2bd6f4f..bb04111 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,2 +1,4 @@ +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536M diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 2819f02..63ab3ae 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/example/android/proguard-android.txt b/example/android/proguard-android.txt new file mode 100644 index 0000000..e69de29 diff --git a/example/android/proguard-rules.pro b/example/android/proguard-rules.pro new file mode 100644 index 0000000..4194f7b --- /dev/null +++ b/example/android/proguard-rules.pro @@ -0,0 +1,5 @@ +-keep class com.finogeeks.** {*;} + +# tbs +-keep class com.tencent.smtt.** {*;} +-keep class com.tencent.tbs.** {*;} \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index a925781..57afd6e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'dart:async'; - -import 'package:flutter/services.dart'; +import 'dart:io'; import 'package:mop/mop.dart'; void main() => runApp(MyApp()); @@ -15,27 +14,24 @@ class _MyAppState extends State { @override void initState() { super.initState(); - initPlatformState(); + init(); } // Platform messages are asynchronous, so we initialize in an async method. - Future initPlatformState() async { - String platformVersion; - // Platform messages may fail, so we use a try/catch PlatformException. - try { - platformVersion = await Mop.instance.platformVersion; - print(platformVersion); - } on PlatformException { - platformVersion = 'Failed to get platform version.'; + Future init() async { + if (Platform.isIOS) { + //com.finogeeks.mopExample + final res = await Mop.instance.initialize( + '22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6', + apiServer: 'https://mp.finogeeks.com', apiPrefix: '/api/v1/mop'); + print(res); + } else if (Platform.isAndroid) { + //com.finogeeks.mopexample + final res = await Mop.instance.initialize( + '22LyZEib0gLTQdU3MUauARjmmp6QmYgjGb3uHueys1oA', '98c49f97a031b555', + apiServer: 'https://mp.finogeeks.com', apiPrefix: '/api/v1/mop'); + print(res); } - final res = await Mop.instance.initialize( - '22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6', - apiServer: 'https://mp.finogeeks.com', apiPrefix: '/api/v1'); - print(res); - - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. if (!mounted) return; } @@ -44,20 +40,60 @@ class _MyAppState extends State { return MaterialApp( home: Scaffold( appBar: AppBar( - title: const Text('Plugin example app'), + title: const Text('凡泰极客小程序 Flutter 插件'), ), body: Center( - child: FlatButton( - onPressed: () { - // appId: '5e3c147a188211000141e9b1', - // path: "/pages/index/index", - // query: "key1=value1&key2=value2", - // scene: "1001" - Mop.instance.openApplet('5e3c147a188211000141e9b1', - path: '/pages/index/index', query: 'key1=value1&key2=value2'); - }, - child: Text('打开小程序'), - )), + child: Container( + padding: EdgeInsets.only( + top: 20, + ), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5)), + gradient: LinearGradient( + colors: const [Color(0xFF12767e), Color(0xFF0dabb8)], + stops: const [0.0, 1.0], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: FlatButton( + onPressed: () { + Mop.instance.openApplet('5e3c147a188211000141e9b1'); + }, + child: Text( + '打开示例小程序', + style: TextStyle(color: Colors.white), + ), + ), + ), + SizedBox(height: 30), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5)), + gradient: LinearGradient( + colors: const [Color(0xFF12767e), Color(0xFF0dabb8)], + stops: const [0.0, 1.0], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + child: FlatButton( + onPressed: () { + Mop.instance.openApplet('5e4d123647edd60001055df1'); + }, + child: Text( + '打开官方小程序', + style: TextStyle(color: Colors.white), + ), + ), + ), + ], + ), + ), + ), ), ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index 2287015..4f6dda6 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -66,7 +66,7 @@ packages: path: ".." relative: true source: path - version: "0.0.1" + version: "0.1.0" path: dependency: transitive description: diff --git a/ios/mop.podspec b/ios/mop.podspec index 632f08c..b3dc96d 100644 --- a/ios/mop.podspec +++ b/ios/mop.podspec @@ -3,7 +3,7 @@ # Pod::Spec.new do |s| s.name = 'mop' - s.version = '0.0.1' + s.version = '0.1.0' s.summary = 'A new flutter plugin project.' s.description = <<-DESC A new flutter plugin project. @@ -15,7 +15,6 @@ A new flutter plugin project. s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.ios.deployment_target = '8.0' s.dependency 'FinApplet', '2.0.192' diff --git a/lib/mop.dart b/lib/mop.dart index 2d287b3..b32f247 100644 --- a/lib/mop.dart +++ b/lib/mop.dart @@ -65,16 +65,15 @@ class Mop { /// [appId] is required. /// [path] is miniprogram open path. example /pages/index/index /// [query] is miniprogram query parameters. example key1=value1&key2=value2 - /// [scene] is miniprogram scene string. example 1100 /// /// Future openApplet(final String appId, - {final String path, final String query, final String scene}) async { + {final String path, final String query}) async { Map params; if (path != '') { params = { 'appId': appId, - 'params': {'path': path, 'query': query, 'scene': scene} + 'params': {'path': path, 'query': query} }; } else { params = {'appId': appId}; diff --git a/mop.iml b/mop.iml deleted file mode 100644 index 429df7d..0000000 --- a/mop.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 14e5a95..a59783a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,9 @@ name: mop description: A new flutter plugin project. -version: 0.0.1 -author: -homepage: +version: 0.1.1 +authors: + - finogeeks +homepage: https://github.com/finogeeks/flutter-mop-plugin environment: sdk: '>=2.1.0 <3.0.0'