提交 ba1f5abe authored 作者: JarvanMo's avatar JarvanMo

message from wechat

上级 7034b2f6
......@@ -29,6 +29,8 @@ 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 java.util.concurrent.atomic.AtomicBoolean
/** FluwxPlugin */
class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
......@@ -47,6 +49,9 @@ class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
private var fluwxChannel: MethodChannel? = null
private var context: Context? = null
private val attemptToResumeMsgFromWxFlag = AtomicBoolean(false)
private var activityPluginBinding: ActivityPluginBinding? = null
private fun handelIntent(intent: Intent) {
intent.getStringExtra(KEY_FLUWX_REQUEST_INFO_EXT_MSG)?.let {
......@@ -96,10 +101,22 @@ class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
call.method == "openWeChatInvoice" -> openWeChatInvoice(call, result)
call.method == "openUrl" -> openUrl(call, result)
call.method == "openRankList" -> openRankList(result)
call.method == "attemptToResumeMsgFromWx" -> attemptToResumeMsgFromWx(result)
else -> result.notImplemented()
}
}
private fun attemptToResumeMsgFromWx(result: Result) {
if (attemptToResumeMsgFromWxFlag.compareAndSet(false, true)) {
activityPluginBinding?.activity?.intent?.let {
FluwxRequestHandler.handleRequestInfoFromIntent(it)
}
result.success(null)
} else {
result.error("attemptToResumeMsgFromWx error", null, null)
}
}
private fun openWeChatInvoice(call: MethodCall, result: Result) {
if (WXAPiHandler.wxApi == null) {
result.error("Unassigned WxApi", "please config wxapi first", null)
......@@ -127,6 +144,7 @@ class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
shareHandler?.onDestroy()
authHandler?.removeAllListeners()
activityPluginBinding = null
}
override fun onDetachedFromActivity() {
......@@ -141,6 +159,7 @@ class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
// WXAPiHandler.setContext(binding.activity.applicationContext)
activityPluginBinding = binding
handelIntent(binding.activity.intent)
FluwxRequestHandler.handleRequestInfoFromIntent(binding.activity.intent)
shareHandler?.permissionHandler = PermissionHandler(binding.activity)
......@@ -287,6 +306,7 @@ class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
result.success(false)
}
}
private fun openRankList(result: Result) {
val req = OpenRankList.Req()
WXAPiHandler.wxApi?.sendReq(req, SendReqCallback {
......
......@@ -29,6 +29,7 @@ import com.jarvan.fluwx.utils.KEY_FLUWX_REQUEST_INFO_BUNDLE
import com.jarvan.fluwx.utils.KEY_FLUWX_REQUEST_INFO_EXT_MSG
import com.jarvan.fluwx.utils.startFlutterActivity
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelmsg.LaunchFromWX
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX
import java.security.cert.Extension
......@@ -42,6 +43,8 @@ object FluwxRequestHandler {
val type = getInt("_wxapi_command_type", -9999)
if (type == 4) {
handleShowMessageFromWXBundle(this)
} else if (type == 6) {
handleWXLaunchFromWXBundle(this)
}
}
}
......@@ -49,45 +52,65 @@ object FluwxRequestHandler {
private fun handleShowMessageFromWXBundle(bundle: Bundle) =
handleWXShowMessageFromWX(ShowMessageFromWX.Req(bundle))
private fun handleWXLaunchFromWXBundle(bundle: Bundle) =
handleWXLaunchFromWX(LaunchFromWX.Req(bundle))
private fun handleRequest(req: BaseReq) {
when (req) {
is ShowMessageFromWX.Req -> handleWXShowMessageFromWX(req)
is LaunchFromWX.Req -> handleWXLaunchFromWX(req)
}
}
private fun handleWXShowMessageFromWX(req: ShowMessageFromWX.Req) {
val result = mapOf(
"extMsg" to req.message.messageExt
"extMsg" to req.message.messageExt,
"messageAction" to req.message.messageAction,
"description" to req.message.description,
"lang" to req.lang,
"description" to req.country,
)
FluwxPlugin.extMsg = req.message.messageExt;
FluwxPlugin.extMsg = req.message.messageExt
FluwxPlugin.callingChannel?.invokeMethod("onWXShowMessageFromWX", result)
}
private fun handleWXLaunchFromWX(req: LaunchFromWX.Req) {
val result = mapOf(
"extMsg" to req.messageExt,
"messageAction" to req.messageAction,
"lang" to req.lang,
"country" to req.country,
)
FluwxPlugin.callingChannel?.invokeMethod("onWXLaunchFromWX", result)
}
private fun defaultOnReqDelegate(baseReq: BaseReq, activity: Activity) {
// FIXME: 可能是官方的Bug,从微信拉起APP的Intent类型不对,无法跳转回Flutter Activity
// 稳定复现场景:微信版本为7.0.5,小程序SDK为2.7.7
if (baseReq.type == 4) {
// com.tencent.mm.opensdk.constants.ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX = 4
if (!WXAPiHandler.coolBoot) {
handleRequest(baseReq)
activity.startFlutterActivity()
} else {
when (baseReq) {
is ShowMessageFromWX.Req -> {
activity.startFlutterActivity(
wxRequestBundle = Bundle().apply {
baseReq.toBundle(this)
},
bundle = Bundle().apply {
putString(
KEY_FLUWX_REQUEST_INFO_EXT_MSG,
baseReq.message.messageExt
)
})
WXAPiHandler.coolBoot = false
}
// com.tencent.mm.opensdk.constants.ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX = 4
if (!WXAPiHandler.coolBoot) {
handleRequest(baseReq)
activity.startFlutterActivity()
} else {
when (baseReq) {
is ShowMessageFromWX.Req -> {
activity.startFlutterActivity(
wxRequestBundle = Bundle().apply {
baseReq.toBundle(this)
},
bundle = Bundle().apply {
putString(
KEY_FLUWX_REQUEST_INFO_EXT_MSG,
baseReq.message.messageExt
)
})
WXAPiHandler.coolBoot = false
}
}
}
}
......
......@@ -42,7 +42,13 @@ NSUInteger defaultThumbnailSize = 32 * 1024;
typedef void(^FluwxWXReqRunnable)(void);
@implementation FluwxPlugin
@implementation FluwxPlugin {
FlutterMethodChannel *_channel;
WechatAuthSDK *_qrauth;
BOOL _isRunning;
BOOL _attemptToResumeMsgFromWxFlag;
FluwxWXReqRunnable _attemptToResumeMsgFromWxRunnable;
}
const NSString *errStr = @"errStr";
const NSString *errCode = @"errCode";
......@@ -53,35 +59,14 @@ const NSString *country = @"country";
const NSString *description = @"description";
BOOL _isRunning;
FluwxWXReqRunnable _initialWXReqRunnable;
BOOL handleOpenURLByFluwx = YES;
FlutterMethodChannel *channel = nil;
WechatAuthSDK *_qrauth;
NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
+ (void)registerWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
#if TARGET_OS_IPHONE
if (channel == nil) {
#endif
channel = [FlutterMethodChannel
methodChannelWithName:@"com.jarvanmo/fluwx"
binaryMessenger:[registrar messenger]];
FluwxPlugin *instance = [[FluwxPlugin alloc] initWithRegistrar:registrar methodChannel:channel];
[registrar addMethodCallDelegate:instance channel:channel];
[registrar addApplicationDelegate:instance];
#if TARGET_OS_IPHONE
}
#endif
}
- (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar methodChannel:(FlutterMethodChannel *)flutterMethodChannel {
self = [super init];
if (self) {
......@@ -90,8 +75,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
_qrauth = [[WechatAuthSDK alloc] init];
_qrauth.delegate = self;
thumbnailWidth = 150;
channel = flutterMethodChannel;
_channel = flutterMethodChannel;
_attemptToResumeMsgFromWxFlag = false;
#if WECHAT_LOGGING
[WXApi startLogByLevel:WXLogLevelDetail logBlock:^(NSString *log) {
[self logToFlutterWithDetail:log];
......@@ -142,6 +127,17 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
[self handleOpenUrlCall:call result:result];
} else if([@"openWeChatInvoice" isEqualToString:call.method]) {
[self openWeChatInvoice:call result:result];
} else if([@"" isEqualToString:call.method]){
if (!_attemptToResumeMsgFromWxFlag) {
_attemptToResumeMsgFromWxFlag = YES;
if (_attemptToResumeMsgFromWxRunnable != nil) {
_attemptToResumeMsgFromWxRunnable();
_attemptToResumeMsgFromWxRunnable = nil;
}
result(nil);
} else {
result([FlutterError errorWithCode:@"attemptToResumeMsgFromWx error" message:nil details:nil]);
}
}
else if ([@"payWithFluwx" isEqualToString:call.method]) {
#ifndef NO_PAY
......@@ -161,6 +157,16 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
}
}
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {
<#code#>
}
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {
<#code#>
}
- (void)openWeChatInvoice:(FlutterMethodCall *)call result:(FlutterResult)result {
NSString *appId = call.arguments[@"appId"];
......@@ -314,12 +320,16 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
- (void)handleSubscribeWithCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSDictionary *params = call.arguments;
NSString *appId = [params valueForKey:@"appId"];
int scene = [[params valueForKey:@"scene"] intValue];
NSNumber *scene = [params valueForKey:@"scene"];
NSString *templateId = [params valueForKey:@"templateId"];
NSString *reserved = [params valueForKey:@"reserved"];
WXSubscribeMsgReq *req = [WXSubscribeMsgReq new];
req.scene = (UInt32) scene;
#if __LP64__
req.scene = [scene unsignedIntValue];
#else
req.scene = [scene unsignedLongValue];
#endif
req.templateId = templateId;
req.reserved = reserved;
req.openID = appId;
......@@ -419,11 +429,11 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
}
- (void)logToFlutterWithDetail:(NSString *) detail {
if(channel != nil){
if(_channel != nil){
NSDictionary *result = @{
@"detail":detail
};
[channel invokeMethod:@"wechatLog" arguments:result];
[_channel invokeMethod:@"wechatLog" arguments:result];
}
}
......@@ -805,8 +815,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
type: @(messageResp.type),
country: messageResp.country == nil ? @"" : messageResp.country,
lang: messageResp.lang == nil ? @"" : messageResp.lang};
if(channel != nil){
[channel invokeMethod:@"onShareResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onShareResponse" arguments:result];
}
......@@ -825,8 +835,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
};
if(channel != nil){
[channel invokeMethod:@"onAuthResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onAuthResponse" arguments:result];
}
} else if ([resp isKindOfClass:[AddCardToWXCardPackageResp class]]) {
......@@ -870,9 +880,9 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
@"cardItemList":cardItemList
};
if(channel != nil){
if(_channel != nil){
[channel invokeMethod:@"onOpenWechatInvoiceResponse" arguments:result];
[_channel invokeMethod:@"onOpenWechatInvoiceResponse" arguments:result];
}
} else if ([resp isKindOfClass:[WXSubscribeMsgResp class]]) {
......@@ -901,8 +911,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
UInt32 scene = subscribeMsgResp.scene;
result[@"scene"] = @(scene);
if(channel != nil){
[channel invokeMethod:@"onSubscribeMsgResp" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onSubscribeMsgResp" arguments:result];
}
} else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) {
......@@ -925,8 +935,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
// @"extMsg":miniProgramResp.extMsg == nil?@"":miniProgramResp.extMsg
if(channel != nil){
[channel invokeMethod:@"onLaunchMiniProgramResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onLaunchMiniProgramResponse" arguments:result];
}
......@@ -943,8 +953,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
@"resultInfo": [FluwxStringUtil nilToEmpty:businessResp.result],
@"businessType": @(businessResp.businessType),
};
if(channel != nil){
[channel invokeMethod:@"onWXOpenBusinessWebviewResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onWXOpenBusinessWebviewResponse" arguments:result];
}
} else if ([resp isKindOfClass:[WXOpenCustomerServiceResp class]])
......@@ -958,8 +968,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
type: @(customerResp.type),
@"extMsg":[FluwxStringUtil nilToEmpty:customerResp.extMsg]
};
if(channel != nil){
[channel invokeMethod:@"onWXOpenBusinessWebviewResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onWXOpenBusinessWebviewResponse" arguments:result];
}
// 相关错误信息
......@@ -975,8 +985,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
type: @(openBusinessViewResp.type),
@"extMsg":[FluwxStringUtil nilToEmpty:openBusinessViewResp.extMsg]
};
if(channel != nil){
[channel invokeMethod:@"onOpenBusinessViewResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onOpenBusinessViewResponse" arguments:result];
}
// 相关错误信息
......@@ -997,8 +1007,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
@"returnKey": [FluwxStringUtil nilToEmpty:payResp.returnKey],
};
[FluwxDelegate defaultManager].extData = nil;
if(channel != nil){
[channel invokeMethod:@"onPayResponse" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onPayResponse" arguments:result];
}
} else if ([resp isKindOfClass:[WXNontaxPayResp class]]) {
......@@ -1010,24 +1020,54 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
if ([req isKindOfClass:[GetMessageFromWXReq class]]) {
} else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) {
//onWXLaunchFromWX
ShowMessageFromWXReq *showMessageFromWXReq = (ShowMessageFromWXReq *) req;
WXMediaMessage *wmm = showMessageFromWXReq.message;
NSDictionary *result = @{
@"extMsg": wmm.messageExt,
@"messageAction": wmm.messageAction,
@"lang": showMessageFromWXReq.lang,
@"country": showMessageFromWXReq.country,
};
[FluwxDelegate defaultManager].extMsg= wmm.messageExt;
if (_isRunning) {
[_channel invokeMethod:@"onWXShowMessageFromWX" arguments:result];
} else {
__weak typeof(self) weakSelf = self;
_initialWXReqRunnable = ^() {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf->_channel invokeMethod:@"onWXShowMessageFromWX" arguments:result];
};
}
} else if ([req isKindOfClass:[LaunchFromWXReq class]]) {
LaunchFromWXReq *launchFromWXReq = (LaunchFromWXReq *) req;
WXMediaMessage *wmm = launchFromWXReq.message;
NSString *msg = @"";
if (wmm == nil || wmm == NULL || [wmm isKindOfClass:[NSNull class]]) {
msg = @"";
}else {
msg = wmm.messageExt;
if (msg == nil || msg == NULL || [msg isKindOfClass:[NSNull class]]) {
msg = @"";
}
}
NSDictionary *result = @{
@"extMsg": msg
@"extMsg": wmm.messageExt,
@"messageAction": wmm.messageAction,
@"lang": launchFromWXReq.lang,
@"country": launchFromWXReq.country,
};
[FluwxDelegate defaultManager].extMsg= wmm.messageExt;
if (_isRunning) {
[_channel invokeMethod:@"onWXLaunchFromWX" arguments:result];
} else {
__weak typeof(self) weakSelf = self;
_initialWXReqRunnable = ^() {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf->_channel invokeMethod:@"onWXLaunchFromWX" arguments:result];
};
}
if(channel != nil){
[channel invokeMethod:@"onWXShowMessageFromWX" arguments:result];
}
......@@ -1462,8 +1502,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
}
- (void)onQrcodeScanned {
if(channel != nil){
[channel invokeMethod:@"onQRCodeScanned" arguments:@{@"errCode": @0}];
if(_channel != nil){
[_channel invokeMethod:@"onQRCodeScanned" arguments:@{@"errCode": @0}];
}
}
......@@ -1472,8 +1512,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
// if (imageData == nil) {
// imageData = UIImageJPEGRepresentation(image, 1);
// }
if(channel != nil){
[channel invokeMethod:@"onAuthGotQRCode" arguments:@{@"errCode": @0, @"qrCode": imageData}];
if(_channel != nil){
[_channel invokeMethod:@"onAuthGotQRCode" arguments:@{@"errCode": @0, @"qrCode": imageData}];
}
}
......@@ -1483,8 +1523,8 @@ NSObject <FlutterPluginRegistrar> *_fluwxRegistrar;
if (authCode != nil) {
result[@"authCode"] = authCode;
}
if(channel != nil){
[channel invokeMethod:@"onAuthByQRCodeFinished" arguments:result];
if(_channel != nil){
[_channel invokeMethod:@"onAuthByQRCodeFinished" arguments:result];
}
}
......
......@@ -69,7 +69,7 @@ The capability of implementing WeChat SDKs in Flutter. With Fluwx, developers ca
end
s.subspec 'no_pay' do |sp|
sp.dependency 'OpenWeChatSDKNoPay','~> 2.0.2+1'
sp.dependency 'OpenWeChatSDKNoPay','~> 2.0.2+2'
sp.frameworks = 'CoreGraphics', 'Security', 'WebKit'
sp.libraries = 'c++', 'z', 'sqlite3.0'
if debug_logging
......
......@@ -94,6 +94,12 @@ class Fluwx {
return FluwxPlatform.instance.pay(which);
}
/// Try to reload data from cold boot. For example, the app is launched by mini program and
/// we can get ext message by calling this.
Future<void> attemptToResumeMsgFromWx() async {
return FluwxPlatform.instance.attemptToResumeMsgFromWx();
}
/// Subscribe responses from WeChat
subscribeResponse(Function(WeChatResponse response) listener) {
_responseListeners.add(listener);
......
......@@ -183,9 +183,7 @@ class MethodChannelFluwx extends FluwxPlatform {
switch (which) {
case Payment():
return await methodChannel.invokeMethod(
'payWithFluwx',
which.arguments
);
'payWithFluwx', which.arguments);
case HongKongWallet():
return await methodChannel.invokeMethod(
'payWithHongKongWallet', which.arguments);
......@@ -205,6 +203,11 @@ class MethodChannelFluwx extends FluwxPlatform {
return await methodChannel.invokeMethod('stopAuthByQRCode');
}
@override
Future<void> attemptToResumeMsgFromWx() async {
return await methodChannel.invokeMethod("attemptToResumeMsgFromWx");
}
@override
Future<bool> get isSupportOpenBusinessView async =>
await methodChannel.invokeMethod("checkSupportOpenBusinessView");
......
......@@ -113,6 +113,10 @@ abstract class FluwxPlatform extends PlatformInterface {
throw UnimplementedError('authBy() has not been implemented.');
}
Future<void> attemptToResumeMsgFromWx() {
throw UnimplementedError('authBy() has not been implemented.');
}
Future<bool> get isSupportOpenBusinessView async {
throw UnimplementedError(
'isSupportOpenBusinessView() has not been implemented.');
......
......@@ -48,6 +48,8 @@ Map<String, _WeChatResponseInvoker> _nameAndResponseMapper = {
WeChatOpenBusinessViewResponse.fromMap(argument),
"onOpenWechatInvoiceResponse": (Map argument) =>
WeChatOpenInvoiceResponse.fromMap(argument),
"onWXLaunchFromWX": (Map argument) =>
WeChatLaunchFromWXRequest.fromMap(argument),
};
sealed class WeChatResponse {
......@@ -213,8 +215,32 @@ class WeChatQRCodeScannedResponse extends WeChatResponse {
// 获取微信打开App时携带的参数
class WeChatShowMessageFromWXRequest extends WeChatResponse {
final String? country;
final String? lang;
final String? messageAction;
final String? description;
WeChatShowMessageFromWXRequest.fromMap(Map map)
: extMsg = map['extMsg'],
country = map['country'],
messageAction = map['messageAction'],
description = map["description"],
lang = map["lang"],
super._(0, '');
final String? extMsg;
}
class WeChatLaunchFromWXRequest extends WeChatResponse {
final String? country;
final String? lang;
final String? messageAction;
WeChatLaunchFromWXRequest.fromMap(Map map)
: extMsg = map['extMsg'],
country = map['country'],
messageAction = map['messageAction'],
lang = map["lang"],
super._(0, '');
final String? extMsg;
......
......@@ -90,6 +90,12 @@ class MockFluwxPlatform
throw UnimplementedError();
}
@override
Future<void> attemptToResumeMsgFromWx() {
// TODO: implement attemptToResumeMsgFromWx
throw UnimplementedError();
}
}
void main() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论