提交 18da014e authored 作者: JarvanMo's avatar JarvanMo

support qrcode auth & reformat code

上级 ca345025
## 0.6.1
* 支持二维码登录
## 0.6.0 ## 0.6.0
* kotlin升级至1.3.21。 * kotlin升级至1.3.21。
* ios SDK升级至1.8.4。 * ios SDK升级至1.8.4。
......
...@@ -24,7 +24,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler ...@@ -24,7 +24,7 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar import io.flutter.plugin.common.PluginRegistry.Registrar
class FluwxPlugin(private val registrar: Registrar, private val channel: MethodChannel) : MethodCallHandler { class FluwxPlugin(private val registrar: Registrar, channel: MethodChannel) : MethodCallHandler {
companion object { companion object {
@JvmStatic @JvmStatic
fun registerWith(registrar: Registrar): Unit { fun registerWith(registrar: Registrar): Unit {
...@@ -36,7 +36,7 @@ class FluwxPlugin(private val registrar: Registrar, private val channel: MethodC ...@@ -36,7 +36,7 @@ class FluwxPlugin(private val registrar: Registrar, private val channel: MethodC
} }
private val fluwxShareHandler = FluwxShareHandler() private val fluwxShareHandler = FluwxShareHandler()
private val fluwxAuthHandler = FluwxAuthHandler() private val fluwxAuthHandler = FluwxAuthHandler(channel)
private val fluwxPayHandler = FluwxPayHandler() private val fluwxPayHandler = FluwxPayHandler()
private val fluwxLaunchMiniProgramHandler = FluwxLaunchMiniProgramHandler() private val fluwxLaunchMiniProgramHandler = FluwxLaunchMiniProgramHandler()
private val fluwxSubscribeMsgHandler = FluwxSubscribeMsgHandler() private val fluwxSubscribeMsgHandler = FluwxSubscribeMsgHandler()
...@@ -69,6 +69,14 @@ class FluwxPlugin(private val registrar: Registrar, private val channel: MethodC ...@@ -69,6 +69,14 @@ class FluwxPlugin(private val registrar: Registrar, private val channel: MethodC
return return
} }
if ("authByQRCode" == call.method) {
fluwxAuthHandler.authByQRCode(call, result)
}
if ("stopAuthByQRCode" == call.method) {
fluwxAuthHandler.stopAuthByQRCode(result)
}
if (call.method == WeChatPluginMethods.PAY) { if (call.method == WeChatPluginMethods.PAY) {
fluwxPayHandler.pay(call, result) fluwxPayHandler.pay(call, result)
return return
......
...@@ -16,11 +16,39 @@ ...@@ -16,11 +16,39 @@
package com.jarvan.fluwx.handler package com.jarvan.fluwx.handler
import com.tencent.mm.opensdk.diffdev.DiffDevOAuthFactory
import com.tencent.mm.opensdk.diffdev.OAuthErrCode
import com.tencent.mm.opensdk.diffdev.OAuthListener
import com.tencent.mm.opensdk.modelmsg.SendAuth import com.tencent.mm.opensdk.modelmsg.SendAuth
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
internal class FluwxAuthHandler { internal class FluwxAuthHandler(private val methodChannel: MethodChannel) {
// private DiffDevOAuthFactory.getDiffDevOAuth()
private val qrCodeAuth by lazy {
DiffDevOAuthFactory.getDiffDevOAuth()
}
private val qrCodeAuthListener by lazy {
object : OAuthListener {
override fun onAuthFinish(p0: OAuthErrCode, authCode: String?) {
methodChannel.invokeMethod("onAuthByQRCodeFinished", {
"errCode" to p0.code
"authCode" to authCode
})
}
override fun onAuthGotQrcode(p0: String?, p1: ByteArray) {
methodChannel.invokeMethod("onAuthGotQRCode", p1)
}
override fun onQrcodeScanned() {
methodChannel.invokeMethod("onQRCodeScanned", null)
}
}
}
fun sendAuth(call: MethodCall, result: MethodChannel.Result) { fun sendAuth(call: MethodCall, result: MethodChannel.Result) {
val req = SendAuth.Req() val req = SendAuth.Req()
...@@ -35,4 +63,20 @@ internal class FluwxAuthHandler { ...@@ -35,4 +63,20 @@ internal class FluwxAuthHandler {
result.success(WXAPiHandler.wxApi?.sendReq(req)) result.success(WXAPiHandler.wxApi?.sendReq(req))
} }
fun authByQRCode(call: MethodCall, result: MethodChannel.Result) {
val appId = call.argument("appId") ?: ""
val scope = call.argument("scope") ?: ""
val nonceStr = call.argument("nonceStr") ?: ""
val timeStamp = call.argument("timeStamp") ?: ""
val signature = call.argument("signature") ?: ""
// val schemeData = call.argument("schemeData")?:""
qrCodeAuth.auth(appId, scope, nonceStr, timeStamp, signature, qrCodeAuthListener)
}
fun stopAuthByQRCode(result: MethodChannel.Result) {
result.success(qrCodeAuth.stopAuth())
}
} }
\ No newline at end of file
package com.jarvan.fluwx.handler package com.jarvan.fluwx.handler
import android.util.Log
import com.jarvan.fluwx.constant.WechatPluginKeys import com.jarvan.fluwx.constant.WechatPluginKeys
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
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 com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
internal class FluwxLaunchMiniProgramHandler { internal class FluwxLaunchMiniProgramHandler {
fun launchMiniProgram(call: MethodCall,result: MethodChannel.Result){ fun launchMiniProgram(call: MethodCall, result: MethodChannel.Result) {
val req = WXLaunchMiniProgram.Req() val req = WXLaunchMiniProgram.Req()
req.userName = call.argument<String?>("userName") // 填小程序原始id req.userName = call.argument<String?>("userName") // 填小程序原始id
req.path = call.argument<String?>("path")?:"" //拉起小程序页面的可带参路径,不填默认拉起小程序首页 req.path = call.argument<String?>("path") ?: "" //拉起小程序页面的可带参路径,不填默认拉起小程序首页
val type = call.argument("miniProgramType")?:0 val type = call.argument("miniProgramType") ?: 0
req.miniprogramType = when(type){ req.miniprogramType = when (type) {
1 -> WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_TEST 1 -> WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_TEST
2-> WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_PREVIEW 2 -> WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_PREVIEW
else-> WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE else -> WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE
}// 可选打开 开发版,体验版和正式版 }// 可选打开 开发版,体验版和正式版
val done = WXAPiHandler.wxApi?.sendReq(req) val done = WXAPiHandler.wxApi?.sendReq(req)
result.success(mapOf( result.success(mapOf(
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package com.jarvan.fluwx.handler package com.jarvan.fluwx.handler
import android.util.Log
import com.jarvan.fluwx.constant.WeChatPluginMethods import com.jarvan.fluwx.constant.WeChatPluginMethods
import com.jarvan.fluwx.constant.WechatPluginKeys import com.jarvan.fluwx.constant.WechatPluginKeys
import com.tencent.mm.opensdk.modelbase.BaseResp import com.tencent.mm.opensdk.modelbase.BaseResp
...@@ -75,7 +74,7 @@ object FluwxResponseHandler { ...@@ -75,7 +74,7 @@ object FluwxResponseHandler {
response.extMsg?.let { response.extMsg?.let {
// "extMsg" to response.extMsg, // "extMsg" to response.extMsg,
result["extMsg"] = response.extMsg result["extMsg"] = response.extMsg
} }
......
...@@ -103,10 +103,10 @@ internal class FluwxShareHandler { ...@@ -103,10 +103,10 @@ internal class FluwxShareHandler {
private fun shareMiniProgram(call: MethodCall, result: MethodChannel.Result) { private fun shareMiniProgram(call: MethodCall, result: MethodChannel.Result) {
val miniProgramObj = WXMiniProgramObject() val miniProgramObj = WXMiniProgramObject()
miniProgramObj.webpageUrl = call.argument("webPageUrl") // 兼容低版本的网页链接 miniProgramObj.webpageUrl = call.argument("webPageUrl") // 兼容低版本的网页链接
miniProgramObj.miniprogramType = call.argument("miniProgramType")?:0// 正式版:0,测试版:1,体验版:2 miniProgramObj.miniprogramType = call.argument("miniProgramType") ?: 0// 正式版:0,测试版:1,体验版:2
miniProgramObj.userName = call.argument("userName") // 小程序原始id miniProgramObj.userName = call.argument("userName") // 小程序原始id
miniProgramObj.path = call.argument("path") //小程序页面路径 miniProgramObj.path = call.argument("path") //小程序页面路径
miniProgramObj.withShareTicket = call.argument("withShareTicket")?:true miniProgramObj.withShareTicket = call.argument("withShareTicket") ?: true
val msg = WXMediaMessage(miniProgramObj) val msg = WXMediaMessage(miniProgramObj)
msg.title = call.argument(WechatPluginKeys.TITLE) // 小程序消息title msg.title = call.argument(WechatPluginKeys.TITLE) // 小程序消息title
msg.description = call.argument("description") // 小程序消息desc msg.description = call.argument("description") // 小程序消息desc
...@@ -148,7 +148,8 @@ internal class FluwxShareHandler { ...@@ -148,7 +148,8 @@ internal class FluwxShareHandler {
result ?: byteArrayOf() result ?: byteArrayOf()
}.await() }.await()
} }
// private suspend fun getThumbnailByteArrayCommon(registrar: PluginRegistry.Registrar?, thumbnail: String): ByteArray {
// private suspend fun getThumbnailByteArrayCommon(registrar: PluginRegistry.Registrar?, thumbnail: String): ByteArray {
// return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT, { // return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT, {
// val result = WeChatThumbnailUtil.thumbnailForCommon(thumbnail, registrar) // val result = WeChatThumbnailUtil.thumbnailForCommon(thumbnail, registrar)
// result ?: byteArrayOf() // result ?: byteArrayOf()
...@@ -166,9 +167,9 @@ internal class FluwxShareHandler { ...@@ -166,9 +167,9 @@ internal class FluwxShareHandler {
GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT) { GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT) {
val byteArray: ByteArray? = if (imagePath.isNullOrBlank()){ val byteArray: ByteArray? = if (imagePath.isNullOrBlank()) {
byteArrayOf() byteArrayOf()
}else{ } else {
getImageByteArrayCommon(registrar, imagePath!!) getImageByteArrayCommon(registrar, imagePath!!)
} }
...@@ -353,7 +354,8 @@ internal class FluwxShareHandler { ...@@ -353,7 +354,8 @@ internal class FluwxShareHandler {
msg.messageExt = call.argument<String>(WechatPluginKeys.MESSAGE_EXT) msg.messageExt = call.argument<String>(WechatPluginKeys.MESSAGE_EXT)
msg.mediaTagName = call.argument<String>(WechatPluginKeys.MEDIA_TAG_NAME) msg.mediaTagName = call.argument<String>(WechatPluginKeys.MEDIA_TAG_NAME)
req.transaction = call.argument(WechatPluginKeys.TRANSACTION) req.transaction = call.argument(WechatPluginKeys.TRANSACTION)
req.scene = getScene(call.argument(WechatPluginKeys.SCENE)?:WechatPluginKeys.SCENE_SESSION) req.scene = getScene(call.argument(WechatPluginKeys.SCENE)
?: WechatPluginKeys.SCENE_SESSION)
} }
} }
\ No newline at end of file
...@@ -5,7 +5,6 @@ import io.flutter.plugin.common.MethodCall ...@@ -5,7 +5,6 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
/// create 2018/12/20 by cai /// create 2018/12/20 by cai
......
...@@ -61,13 +61,13 @@ public class ShareImageUtil { ...@@ -61,13 +61,13 @@ public class ShareImageUtil {
} else if (path.startsWith(WeChatPluginImageSchema.SCHEMA_FILE)) { } else if (path.startsWith(WeChatPluginImageSchema.SCHEMA_FILE)) {
String pathWithoutUri = path.substring("file://".length()); String pathWithoutUri = path.substring("file://".length());
result = fileToByteArray(registrar,pathWithoutUri); result = fileToByteArray(registrar, pathWithoutUri);
} else if(path.startsWith(WeChatPluginImageSchema.SCHEMA_CONTENT)){ } else if (path.startsWith(WeChatPluginImageSchema.SCHEMA_CONTENT)) {
File file = getFileFromContentProvider(registrar,path); File file = getFileFromContentProvider(registrar, path);
if (file != null) { if (file != null) {
result = fileToByteArray(registrar,file.getAbsolutePath()); result = fileToByteArray(registrar, file.getAbsolutePath());
} }
}else { } else {
// result = handleNetworkImage(registrar, path); // result = handleNetworkImage(registrar, path);
result = Util.inputStreamToByte(openStream(path)); result = Util.inputStreamToByte(openStream(path));
} }
...@@ -88,7 +88,7 @@ public class ShareImageUtil { ...@@ -88,7 +88,7 @@ public class ShareImageUtil {
return Util.bmpToByteArray(bmp, true); return Util.bmpToByteArray(bmp, true);
} }
private static byte[] fileToByteArray(PluginRegistry.Registrar registrar, String pathWithoutUri){ private static byte[] fileToByteArray(PluginRegistry.Registrar registrar, String pathWithoutUri) {
byte[] result = null; byte[] result = null;
Bitmap bmp = null; Bitmap bmp = null;
...@@ -97,7 +97,7 @@ public class ShareImageUtil { ...@@ -97,7 +97,7 @@ public class ShareImageUtil {
int byteCount; int byteCount;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
byteCount = bmp.getAllocationByteCount(); byteCount = bmp.getAllocationByteCount();
}else { } else {
byteCount = bmp.getByteCount(); byteCount = bmp.getByteCount();
} }
if (byteCount >= WX_MAX_IMAGE_BYTE_SIZE) { if (byteCount >= WX_MAX_IMAGE_BYTE_SIZE) {
...@@ -181,7 +181,7 @@ public class ShareImageUtil { ...@@ -181,7 +181,7 @@ public class ShareImageUtil {
} }
private static File getFileFromContentProvider(PluginRegistry.Registrar registrar,String path) { private static File getFileFromContentProvider(PluginRegistry.Registrar registrar, String path) {
Source source = null; Source source = null;
BufferedSink sink = null; BufferedSink sink = null;
...@@ -211,7 +211,7 @@ public class ShareImageUtil { ...@@ -211,7 +211,7 @@ public class ShareImageUtil {
source.close(); source.close();
sink.close(); sink.close();
} catch (IOException e) { } catch (IOException e) {
Log.i("fluwx","reading image failed:\n" + e.getMessage()); Log.i("fluwx", "reading image failed:\n" + e.getMessage());
} }
return file; return file;
......
...@@ -22,7 +22,6 @@ import android.graphics.Canvas; ...@@ -22,7 +22,6 @@ import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.Log; import android.util.Log;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
......
...@@ -18,13 +18,11 @@ package com.jarvan.fluwx.wxapi ...@@ -18,13 +18,11 @@ package com.jarvan.fluwx.wxapi
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import com.jarvan.fluwx.handler.FluwxResponseHandler import com.jarvan.fluwx.handler.FluwxResponseHandler
import com.jarvan.fluwx.handler.WXAPiHandler import com.jarvan.fluwx.handler.WXAPiHandler
import com.tencent.mm.opensdk.modelbase.BaseReq import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
import java.lang.Exception
open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
...@@ -38,7 +36,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -38,7 +36,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
try { try {
WXAPiHandler.wxApi?.handleIntent(intent, this) WXAPiHandler.wxApi?.handleIntent(intent, this)
}catch (e:Exception){ } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
finish() finish()
} }
...@@ -52,7 +50,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -52,7 +50,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
try { try {
WXAPiHandler.wxApi?.handleIntent(intent, this) WXAPiHandler.wxApi?.handleIntent(intent, this)
}catch (e:Exception){ } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
finish() finish()
} }
......
...@@ -16,5 +16,4 @@ ...@@ -16,5 +16,4 @@
package com.jarvan.fluwx.wxapi package com.jarvan.fluwx.wxapi
open class WXEntryActivity : FluwxWXEntryActivity()
open class WXEntryActivity :FluwxWXEntryActivity() \ No newline at end of file
\ No newline at end of file
...@@ -16,5 +16,4 @@ ...@@ -16,5 +16,4 @@
package com.jarvan.fluwx.wxapi package com.jarvan.fluwx.wxapi
open class WXPayEntryActivity : FluwxWXEntryActivity()
open class WXPayEntryActivity :FluwxWXEntryActivity() \ No newline at end of file
\ No newline at end of file
...@@ -6,7 +6,7 @@ buildscript { ...@@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.1' classpath 'com.android.tools.build:gradle:3.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
......
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart' as fluwx;
class AuthByQRCodePage extends StatefulWidget {
@override
_AuthByQRCodePageState createState() => _AuthByQRCodePageState();
}
class _AuthByQRCodePageState extends State<AuthByQRCodePage> {
String _status = "status";
Uint8List _image;
@override
void initState() {
super.initState();
fluwx.onAuthByQRCodeFinished.listen((data) => {
setState(() {
_status =
"errorCode=>${data.errorCode}\nauthCode=>${data.authCode}";
})
});
fluwx.onAuthGotQRCode.listen((image) {
setState(() {
_image = image;
});
});
fluwx.onQRCodeScanned.listen((scanned) {
setState(() {
_status = "scanned";
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AuthByQRCode"),
),
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
fluwx.authByQRCode(
appId: "wxd930ea5d5a258f4f",
scope: "noncestr",
nonceStr: "nonceStr",
timeStamp: "1417508194",
signature: "429eaaa13fd71efbc3fd344d0a9a9126835e7303");
},
child: Text("AUTH NOW"),
),
Text(_status),
_qrCode()
],
),
);
}
Widget _qrCode() {
if (_image == null) {
return Container();
} else {
return Image.memory(_image);
}
}
}
...@@ -7,8 +7,6 @@ class LaunchMiniProgramPage extends StatefulWidget { ...@@ -7,8 +7,6 @@ class LaunchMiniProgramPage extends StatefulWidget {
} }
class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> { class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> {
String _result = "无"; String _result = "无";
@override @override
...@@ -19,14 +17,12 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> { ...@@ -19,14 +17,12 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> {
_result = "${data.extMsg}"; _result = "${data.extMsg}";
}); });
}); });
} }
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
_result = null; _result = null;
} }
@override @override
...@@ -39,9 +35,7 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> { ...@@ -39,9 +35,7 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> {
children: <Widget>[ children: <Widget>[
OutlineButton( OutlineButton(
onPressed: () { onPressed: () {
fluwx.launchMiniProgram( fluwx.launchMiniProgram(username: "gh_d43f693ca31f").then((data) {
username: "gh_d43f693ca31f"
).then((data) {
print(data); print(data);
}); });
}, },
......
...@@ -2,8 +2,10 @@ import 'dart:async'; ...@@ -2,8 +2,10 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart' as fluwx; import 'package:fluwx/fluwx.dart' as fluwx;
import 'package:fluwx_example/launch_mini_program_page.dart';
import 'package:fluwx_example/subscribe_message_page.dart'; import 'package:fluwx_example/subscribe_message_page.dart';
import 'auth_by_qr_code_page.dart';
import 'pay_page.dart'; import 'pay_page.dart';
import 'send_auth.dart'; import 'send_auth.dart';
import 'share_image_page.dart'; import 'share_image_page.dart';
...@@ -12,7 +14,6 @@ import 'share_music.dart'; ...@@ -12,7 +14,6 @@ import 'share_music.dart';
import 'share_text_image.dart'; import 'share_text_image.dart';
import 'share_video_page.dart'; import 'share_video_page.dart';
import 'share_web_page.dart'; import 'share_web_page.dart';
import 'package:fluwx_example/launch_mini_program_page.dart';
void main() => runApp(new MyApp()); void main() => runApp(new MyApp());
...@@ -28,8 +29,12 @@ class _MyAppState extends State<MyApp> { ...@@ -28,8 +29,12 @@ class _MyAppState extends State<MyApp> {
_initFluwx(); _initFluwx();
} }
_initFluwx() async{ _initFluwx() async {
await fluwx.register(appId: "wxd930ea5d5a258f4f", doOnAndroid: true, doOnIOS: true, enableMTA: false); await fluwx.register(
appId: "wxd930ea5d5a258f4f",
doOnAndroid: true,
doOnIOS: true,
enableMTA: false);
var result = await fluwx.isWeChatInstalled(); var result = await fluwx.isWeChatInstalled();
print("is installed $result"); print("is installed $result");
} }
...@@ -51,6 +56,7 @@ class _MyAppState extends State<MyApp> { ...@@ -51,6 +56,7 @@ class _MyAppState extends State<MyApp> {
"pay": (context) => PayPage(), "pay": (context) => PayPage(),
"launchMiniProgram": (context) => LaunchMiniProgramPage(), "launchMiniProgram": (context) => LaunchMiniProgramPage(),
"subscribeMessage": (ctx) => SubscribeMessagePage(), "subscribeMessage": (ctx) => SubscribeMessagePage(),
"AuthByQRCode": (ctx) => AuthByQRCodePage()
}, },
home: new Scaffold( home: new Scaffold(
appBar: new AppBar( appBar: new AppBar(
...@@ -147,6 +153,14 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -147,6 +153,14 @@ class ShareSelectorPage extends StatelessWidget {
}, },
child: const Text("SubscribeMessage")), child: const Text("SubscribeMessage")),
), ),
Padding(
padding: const EdgeInsets.all(8.0),
child: new OutlineButton(
onPressed: () {
Navigator.of(context).pushNamed("AuthByQRCode");
},
child: const Text("AuthByQRCode")),
),
], ],
), ),
); );
......
...@@ -45,7 +45,8 @@ class _PayPageState extends State<PayPage> { ...@@ -45,7 +45,8 @@ class _PayPageState extends State<PayPage> {
Map<String, dynamic> result = json.decode(data); Map<String, dynamic> result = json.decode(data);
print(result['appid']); print(result['appid']);
print(result["timestamp"]); print(result["timestamp"]);
fluwx.pay( fluwx
.pay(
appId: result['appid'].toString(), appId: result['appid'].toString(),
partnerId: result['partnerid'].toString(), partnerId: result['partnerid'].toString(),
prepayId: result['prepayid'].toString(), prepayId: result['prepayid'].toString(),
......
...@@ -7,7 +7,6 @@ class SendAuthPage extends StatefulWidget { ...@@ -7,7 +7,6 @@ class SendAuthPage extends StatefulWidget {
} }
class _SendAuthPageState extends State<SendAuthPage> { class _SendAuthPageState extends State<SendAuthPage> {
String _result = "无"; String _result = "无";
@override @override
...@@ -18,14 +17,12 @@ class _SendAuthPageState extends State<SendAuthPage> { ...@@ -18,14 +17,12 @@ class _SendAuthPageState extends State<SendAuthPage> {
_result = "${data.errCode}"; _result = "${data.errCode}";
}); });
}); });
} }
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
_result = null; _result = null;
} }
@override @override
...@@ -38,11 +35,10 @@ class _SendAuthPageState extends State<SendAuthPage> { ...@@ -38,11 +35,10 @@ class _SendAuthPageState extends State<SendAuthPage> {
children: <Widget>[ children: <Widget>[
OutlineButton( OutlineButton(
onPressed: () { onPressed: () {
fluwx.sendAuth( fluwx
.sendAuth(
scope: "snsapi_userinfo", state: "wechat_sdk_demo_test") scope: "snsapi_userinfo", state: "wechat_sdk_demo_test")
.then((data) { .then((data) {});
});
}, },
child: const Text("send auth"), child: const Text("send auth"),
), ),
......
...@@ -7,17 +7,17 @@ class ShareImagePage extends StatefulWidget { ...@@ -7,17 +7,17 @@ class ShareImagePage extends StatefulWidget {
} }
class _ShareImagePageState extends State<ShareImagePage> { class _ShareImagePageState extends State<ShareImagePage> {
fluwx.WeChatScene scene = fluwx.WeChatScene.SESSION; fluwx.WeChatScene scene = fluwx.WeChatScene.SESSION;
String _imagePath = String _imagePath =
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534614311230&di=b17a892b366b5d002f52abcce7c4eea0&imgtype=0&src=http%3A%2F%2Fimg.mp.sohu.com%2Fupload%2F20170516%2F51296b2673704ae2992d0a28c244274c_th.png"; "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534614311230&di=b17a892b366b5d002f52abcce7c4eea0&imgtype=0&src=http%3A%2F%2Fimg.mp.sohu.com%2Fupload%2F20170516%2F51296b2673704ae2992d0a28c244274c_th.png";
String _thumbnail = "assets://logo.png"; String _thumbnail = "assets://logo.png";
String _response =""; String _response = "";
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fluwx.responseFromShare.listen((data){ fluwx.responseFromShare.listen((data) {
setState(() { setState(() {
_response = data.errCode.toString(); _response = data.errCode.toString();
}); });
...@@ -91,7 +91,6 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -91,7 +91,6 @@ class _ShareImagePageState extends State<ShareImagePage> {
) )
], ],
), ),
Text(_response) Text(_response)
], ],
), ),
......
...@@ -19,7 +19,6 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> { ...@@ -19,7 +19,6 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
......
...@@ -7,7 +7,6 @@ class ShareMusicPage extends StatefulWidget { ...@@ -7,7 +7,6 @@ class ShareMusicPage extends StatefulWidget {
} }
class _ShareMusicPageState extends State<ShareMusicPage> { class _ShareMusicPageState extends State<ShareMusicPage> {
String _musicUrl = String _musicUrl =
"http://staff2.ustc.edu.cn/~wdw/softdown/index.asp/0042515_05.ANDY.mp3"; "http://staff2.ustc.edu.cn/~wdw/softdown/index.asp/0042515_05.ANDY.mp3";
String _musicLowBandUrl = "http://www.qq.com"; String _musicLowBandUrl = "http://www.qq.com";
...@@ -19,7 +18,6 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -19,7 +18,6 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
......
...@@ -7,7 +7,6 @@ class ShareTextPage extends StatefulWidget { ...@@ -7,7 +7,6 @@ class ShareTextPage extends StatefulWidget {
} }
class _ShareTextPageState extends State<ShareTextPage> { class _ShareTextPageState extends State<ShareTextPage> {
String _text = "share text from fluwx"; String _text = "share text from fluwx";
fluwx.WeChatScene scene = fluwx.WeChatScene.SESSION; fluwx.WeChatScene scene = fluwx.WeChatScene.SESSION;
......
...@@ -7,7 +7,6 @@ class ShareVideoPage extends StatefulWidget { ...@@ -7,7 +7,6 @@ class ShareVideoPage extends StatefulWidget {
} }
class _ShareMusicPageState extends State<ShareVideoPage> { class _ShareMusicPageState extends State<ShareVideoPage> {
String _videoUrl = "http://www.qq.com"; String _videoUrl = "http://www.qq.com";
String _videoLowBandUrl = "http://www.qq.com"; String _videoLowBandUrl = "http://www.qq.com";
String _title = "Beyond"; String _title = "Beyond";
......
...@@ -9,7 +9,6 @@ class ShareWebPagePage extends StatefulWidget { ...@@ -9,7 +9,6 @@ class ShareWebPagePage extends StatefulWidget {
} }
class ShareWebPagePageState extends State<ShareWebPagePage> { class ShareWebPagePageState extends State<ShareWebPagePage> {
String _url = "share text from fluwx"; String _url = "share text from fluwx";
String _title = "Fluwx"; String _title = "Fluwx";
String _thumnail = "assets://images/logo.png"; String _thumnail = "assets://images/logo.png";
...@@ -18,7 +17,6 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -18,7 +17,6 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
......
...@@ -8,9 +8,11 @@ class SubscribeMessagePage extends StatefulWidget { ...@@ -8,9 +8,11 @@ class SubscribeMessagePage extends StatefulWidget {
/// see wechat [document](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500434436_aWfqW&token=&lang=zh_CN) /// see wechat [document](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500434436_aWfqW&token=&lang=zh_CN)
class _SubscribeMessagePageState extends State<SubscribeMessagePage> { class _SubscribeMessagePageState extends State<SubscribeMessagePage> {
TextEditingController appId = TextEditingController(text: "wx316f9c82e99ac105"); TextEditingController appId =
TextEditingController(text: "wx316f9c82e99ac105");
TextEditingController scene = TextEditingController(text: "1"); TextEditingController scene = TextEditingController(text: "1");
TextEditingController templateId = TextEditingController(text: "cm_vM2k3IjHcYbkGUeAfL6Fja_7Pgv4Hx_q4tA253Ss"); TextEditingController templateId = TextEditingController(
text: "cm_vM2k3IjHcYbkGUeAfL6Fja_7Pgv4Hx_q4tA253Ss");
TextEditingController reserved = TextEditingController(text: "123"); TextEditingController reserved = TextEditingController(text: "123");
@override @override
...@@ -41,7 +43,8 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> { ...@@ -41,7 +43,8 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> {
children: <Widget>[ children: <Widget>[
_buildTextField(title: "appId", textEditController: appId), _buildTextField(title: "appId", textEditController: appId),
_buildTextField(title: "scene", textEditController: scene), _buildTextField(title: "scene", textEditController: scene),
_buildTextField(title: "templateId", textEditController: templateId), _buildTextField(
title: "templateId", textEditController: templateId),
_buildTextField(title: "reserved", textEditController: reserved), _buildTextField(title: "reserved", textEditController: reserved),
FlatButton( FlatButton(
child: Text('request once subscribe message'), child: Text('request once subscribe message'),
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
library fluwx; library fluwx;
export 'src/fluwx_iml.dart'; export 'src/fluwx_iml.dart';
export 'src/models/wechat_auth_by_qr_code.dart';
export 'src/models/wechat_response.dart'; export 'src/models/wechat_response.dart';
export 'src/models/wechat_share_models.dart'; export 'src/models/wechat_share_models.dart';
export 'src/wechat_type.dart'; export 'src/wechat_type.dart';
...@@ -14,14 +14,16 @@ ...@@ -14,14 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'models/wechat_auth_by_qr_code.dart';
import 'models/wechat_response.dart'; import 'models/wechat_response.dart';
import 'models/wechat_share_models.dart'; import 'models/wechat_share_models.dart';
import 'wechat_type.dart';
import 'package:flutter/foundation.dart';
import 'utils/utils.dart'; import 'utils/utils.dart';
import 'wechat_type.dart';
StreamController<WeChatShareResponse> _responseShareController = StreamController<WeChatShareResponse> _responseShareController =
new StreamController.broadcast(); new StreamController.broadcast();
...@@ -58,6 +60,24 @@ StreamController<WeChatSubscribeMsgResp> _responseFromSubscribeMsg = ...@@ -58,6 +60,24 @@ StreamController<WeChatSubscribeMsgResp> _responseFromSubscribeMsg =
Stream<WeChatSubscribeMsgResp> get responseFromSubscribeMsg => Stream<WeChatSubscribeMsgResp> get responseFromSubscribeMsg =>
_responseFromSubscribeMsg.stream; _responseFromSubscribeMsg.stream;
StreamController<AuthByQRCodeResult> _authByQRCodeFinishedController =
new StreamController.broadcast();
///invoked when [authByQRCode] finished
Stream<AuthByQRCodeResult> get onAuthByQRCodeFinished =>
_authByQRCodeFinishedController.stream;
StreamController<Uint8List> _onAuthGotQRCodeController =
new StreamController.broadcast();
///when QRCode received
Stream<Uint8List> get onAuthGotQRCode => _onAuthGotQRCodeController.stream;
StreamController _onQRCodeScannedController = new StreamController();
///after uer scanned the QRCode you just received
Stream get onQRCodeScanned => _onQRCodeScannedController.stream;
final MethodChannel _channel = const MethodChannel('com.jarvanmo/fluwx') final MethodChannel _channel = const MethodChannel('com.jarvanmo/fluwx')
..setMethodCallHandler(_handler); ..setMethodCallHandler(_handler);
...@@ -77,20 +97,17 @@ Future<dynamic> _handler(MethodCall methodCall) { ...@@ -77,20 +97,17 @@ Future<dynamic> _handler(MethodCall methodCall) {
} else if ("onSubscribeMsgResp" == methodCall.method) { } else if ("onSubscribeMsgResp" == methodCall.method) {
_responseFromSubscribeMsg _responseFromSubscribeMsg
.add(WeChatSubscribeMsgResp.fromMap(methodCall.arguments)); .add(WeChatSubscribeMsgResp.fromMap(methodCall.arguments));
} else if ("onAuthByQRCodeFinished" == methodCall.method) {
_handleOnAuthByQRCodeFinished(methodCall);
} else if ("onAuthGotQRCode" == methodCall.method) {
_onAuthGotQRCodeController.add(methodCall.arguments);
} else if ("onQRCodeScanned" == methodCall.method) {
_onQRCodeScannedController.add(null);
} }
return Future.value(true); return Future.value(true);
} }
const Map<Type, String> _shareModelMethodMapper = {
WeChatShareTextModel: "shareText",
WeChatShareImageModel: "shareImage",
WeChatShareMusicModel: "shareMusic",
WeChatShareVideoModel: "shareVideo",
WeChatShareWebPageModel: "shareWebPage",
WeChatShareMiniProgramModel: "shareMiniProgram"
};
///[appId] is not necessary. ///[appId] is not necessary.
///if [doOnIOS] is true ,fluwx will register WXApi on iOS. ///if [doOnIOS] is true ,fluwx will register WXApi on iOS.
///if [doOnAndroid] is true, fluwx will register WXApi on Android. ///if [doOnAndroid] is true, fluwx will register WXApi on Android.
...@@ -108,11 +125,15 @@ Future register( ...@@ -108,11 +125,15 @@ Future register(
} }
///we don't need the response any longer if params are true. ///we don't need the response any longer if params are true.
void dispose( void dispose({
{shareResponse: true, shareResponse: true,
authResponse: true, authResponse: true,
paymentResponse: true, paymentResponse: true,
launchMiniProgramResponse: true}) { launchMiniProgramResponse: true,
onAuthByQRCodeFinished: true,
onAuthGotQRCode: true,
onQRCodeScanned: true,
}) {
if (shareResponse) { if (shareResponse) {
_responseShareController.close(); _responseShareController.close();
} }
...@@ -127,6 +148,18 @@ void dispose( ...@@ -127,6 +148,18 @@ void dispose(
if (paymentResponse) { if (paymentResponse) {
_responseAuthController.close(); _responseAuthController.close();
} }
if (onAuthByQRCodeFinished) {
_authByQRCodeFinishedController.close();
}
if (onAuthGotQRCode) {
_onAuthGotQRCodeController.close();
}
if (onQRCodeScanned) {
_onQRCodeScannedController.close();
}
} }
// static Future unregisterApp(RegisterModel model) async { // static Future unregisterApp(RegisterModel model) async {
...@@ -148,8 +181,12 @@ Future share(WeChatShareModel model) async { ...@@ -148,8 +181,12 @@ Future share(WeChatShareModel model) async {
} }
} }
/// in order to get code from WeChat. /// The WeChat-Login is under Auth-2.0
/// for more information please visit: /// This method login with native WeChat app.
/// For users without WeChat app, please use [authByQRCode] instead
/// This method only supports getting AuthCode,this is first step to login with WeChat
/// Once AuthCode got, you need to request Access_Token
/// For more information please visit:
/// * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token= /// * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=
Future sendAuth({String openId, @required String scope, String state}) async { Future sendAuth({String openId, @required String scope, String state}) async {
// "scope": scope, "state": state, "openId": openId // "scope": scope, "state": state, "openId": openId
...@@ -159,6 +196,39 @@ Future sendAuth({String openId, @required String scope, String state}) async { ...@@ -159,6 +196,39 @@ Future sendAuth({String openId, @required String scope, String state}) async {
"sendAuth", {"scope": scope, "state": state, "openId": openId}); "sendAuth", {"scope": scope, "state": state, "openId": openId});
} }
/// Sometimes WeChat is not installed on users's devices.However we can
/// request a QRCode so that we can get AuthCode by scanning the QRCode
/// All required params must not be null or empty
/// [schemeData] only works on iOS
/// see * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=215238808828h4XN&token=&lang=zh_CN
Future authByQRCode(
{@required String appId,
@required String scope,
@required String nonceStr,
@required String timeStamp,
@required String signature,
String schemeData}) async {
assert(appId != null && appId.isNotEmpty);
assert(scope != null && scope.isNotEmpty);
assert(nonceStr != null && nonceStr.isNotEmpty);
assert(timeStamp != null && timeStamp.isNotEmpty);
assert(signature != null && signature.isNotEmpty);
return await _channel.invokeMethod("authByQRCode", {
"appId": appId,
"scope": scope,
"nonceStr": nonceStr,
"timeStamp": timeStamp,
"signature": signature,
"schemeData": schemeData
});
}
/// stop auth
Future stopAuthByQRCode() async {
return await _channel.invokeMethod("stopAuthByQRCode");
}
/// open mini-program /// open mini-program
/// see [WXMiniProgramType] /// see [WXMiniProgramType]
Future launchMiniProgram( Future launchMiniProgram(
...@@ -230,3 +300,28 @@ Future subscribeMsg({ ...@@ -230,3 +300,28 @@ Future subscribeMsg({
}, },
); );
} }
_handleOnAuthByQRCodeFinished(MethodCall methodCall) {
int errCode = methodCall.arguments("errCode");
_authByQRCodeFinishedController.add(AuthByQRCodeResult(
methodCall.arguments("authCode"),
_authByQRCodeErrorCodes[errCode] ?? AuthByQRCodeErrorCode.UNKNOWN));
}
const Map<Type, String> _shareModelMethodMapper = {
WeChatShareTextModel: "shareText",
WeChatShareImageModel: "shareImage",
WeChatShareMusicModel: "shareMusic",
WeChatShareVideoModel: "shareVideo",
WeChatShareWebPageModel: "shareWebPage",
WeChatShareMiniProgramModel: "shareMiniProgram"
};
const Map<int, AuthByQRCodeErrorCode> _authByQRCodeErrorCodes = {
0: AuthByQRCodeErrorCode.OK,
-1: AuthByQRCodeErrorCode.NORMAL_ERR,
-2: AuthByQRCodeErrorCode.NETWORK_ERR,
-3: AuthByQRCodeErrorCode.JSON_DECODE_ERR,
-4: AuthByQRCodeErrorCode.CANCEL,
-5: AuthByQRCodeErrorCode.AUTH_STOPPED
};
//WechatAuth_Err_OK(0),
//WechatAuth_Err_NormalErr(-1),
//WechatAuth_Err_NetworkErr(-2),
//WechatAuth_Err_JsonDecodeErr(-3),
//WechatAuth_Err_Cancel(-4),
//WechatAuth_Err_Timeout(-5),
//WechatAuth_Err_Auth_Stopped(-6);
enum AuthByQRCodeErrorCode {
OK,
NORMAL_ERR,
NETWORK_ERR,
JSON_DECODE_ERR,
CANCEL,
TIMEOUT,
AUTH_STOPPED,
UNKNOWN
}
class AuthByQRCodeResult {
final String authCode;
final AuthByQRCodeErrorCode errorCode;
AuthByQRCodeResult(this.authCode, this.errorCode);
}
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
*/ */
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../wechat_type.dart';
import '../utils/utils.dart'; import '../utils/utils.dart';
import '../wechat_type.dart';
const String _scene = "scene"; const String _scene = "scene";
const String _transaction = "transaction"; const String _transaction = "transaction";
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论