Unverified 提交 f9231551 authored 作者: JarvanMo's avatar JarvanMo 提交者: GitHub

Merge branch 'master' into master

## 1.0.3
* 修复一些小问题
## 1.0.2
* 修复无法Android上分享大图的问题
## 1.0.1
* 修复一些小问题
## 1.0.0
* ios不必再重写AppDelegate
## 0.6.3
* 免密支付
* 支持打开微信App了
* 升级了Android
## 0.6.2
* 对android进行了升级
## 0.6.1 ## 0.6.1
* 支持二维码登录 * 支持二维码登录
......
...@@ -22,7 +22,9 @@ QQ Group:892398530。 ...@@ -22,7 +22,9 @@ QQ Group:892398530。
* Pay. * Pay.
* Launch Mini-Program. * Launch Mini-Program.
* Subscribe Message. * Subscribe Message.
* Auth By QRCode * Auth By QRCode.
* Sign Auto-Deduct.
* Open WeChat App.
## Sample ## Sample
...@@ -30,6 +32,8 @@ QQ Group:892398530。 ...@@ -30,6 +32,8 @@ QQ Group:892398530。
[watch charged video here](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4) [watch charged video here](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4)
[upgrade to 1.0.0 or above](./doc/QUESTIONS.md)
## Dependencies ## Dependencies
Add the following dependencies in your `pubspec.yaml` file: Add the following dependencies in your `pubspec.yaml` file:
...@@ -69,11 +73,11 @@ Before using`Fluwx`,you should init `FLuwx`: ...@@ -69,11 +73,11 @@ Before using`Fluwx`,you should init `FLuwx`:
* [Payment](./doc/WXPay.md) * [Payment](./doc/WXPay.md)
* [Launch Mini-Program](./doc/LAUNCH_MINI_PROGRAM.md) * [Launch Mini-Program](./doc/LAUNCH_MINI_PROGRAM.md)
* [Subscribe Message](./doc/SUBSCRIBE_MESSAGE.md) * [Subscribe Message](./doc/SUBSCRIBE_MESSAGE.md)
* [Response](./doc/RESPONSE.md)
* [Auth By QRCode](./doc/AUTH_BY_QR_CODE.md) * [Auth By QRCode](./doc/AUTH_BY_QR_CODE.md)
* [Sign Auto-Deduct](./doc/AUTO_DEDUCT.md)
* [Obtain Response From WeChat](./doc/RESPONSE.md)
### Other ### Other
* [Using Swift?](./doc/USING_SWIFT.md)
* [Having Questions?](./doc/QUESTIONS.md) * [Having Questions?](./doc/QUESTIONS.md)
### Waiting ### Waiting
......
...@@ -22,7 +22,8 @@ QQ群:892398530。 ...@@ -22,7 +22,8 @@ QQ群:892398530。
* 打开小程序。 * 打开小程序。
* 一次性订阅消息。 * 一次性订阅消息。
* 二维码登录。 * 二维码登录。
* 签约免密支付。
* 打开微信。
## 示例 ## 示例
...@@ -30,6 +31,7 @@ QQ群:892398530。 ...@@ -30,6 +31,7 @@ QQ群:892398530。
[收费视频教程点这里](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4) [收费视频教程点这里](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4)
[升级到1.0.0或者更高](./doc/QUESTIONS_CN.md)
## 引入 ## 引入
...@@ -66,14 +68,13 @@ dependencies: ...@@ -66,14 +68,13 @@ dependencies:
* [Auth](./doc/SEND_AUTH_CN.md) * [Auth](./doc/SEND_AUTH_CN.md)
* [支付](./doc/WXPay_CN.md) * [支付](./doc/WXPay_CN.md)
* [打开小程序](./doc/LAUNCH_MINI_PROGRAM_CN.md) * [打开小程序](./doc/LAUNCH_MINI_PROGRAM_CN.md)
* [一次性订阅消息](./doc/SUBSCRIBE_MESSAGE_CN.md) * [一次性订阅消息](./doc/SUBSCRIBE_MESSAGE_CN.md)。。
* [微信回调](./doc/RESPONSE_CN.md)
* [二维码登录](./doc/AUTH_BY_QR_CODE_CN.md) * [二维码登录](./doc/AUTH_BY_QR_CODE_CN.md)
* [签约免密支付](./doc/AUTO_DEDUCT_CN.md)
* [接收微信响应](./doc/RESPONSE_CN.md)
### Q&A ### Q&A
请先看文档,再看Q&A,再查看issue,自我排查错误,方便你我他。依然无法解决的问题可以加群提问。 请先看文档,再看Q&A,再查看issue,自我排查错误,方便你我他。依然无法解决的问题可以加群提问。
* [使用Swift?](./doc/USING_SWIFT_CN.md)
* [常见问题Q&A](./doc/QUESTIONS_CN.md) * [常见问题Q&A](./doc/QUESTIONS_CN.md)
...@@ -86,6 +87,8 @@ dependencies: ...@@ -86,6 +87,8 @@ dependencies:
### 欢迎关注公众号 ### 欢迎关注公众号
![subscribe](./arts/wx_subscription.png) ![subscribe](./arts/wx_subscription.png)
## LICENSE ## LICENSE
......
...@@ -2,14 +2,14 @@ group 'com.jarvan.fluwx' ...@@ -2,14 +2,14 @@ group 'com.jarvan.fluwx'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
buildscript { buildscript {
ext.kotlin_version = '1.3.21' ext.kotlin_version = '1.3.31'
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.1' classpath 'com.android.tools.build:gradle:3.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
...@@ -45,5 +45,5 @@ dependencies { ...@@ -45,5 +45,5 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
implementation 'top.zibin:Luban:1.1.8' implementation 'top.zibin:Luban:1.1.8'
implementation 'com.squareup.okhttp3:okhttp:3.11.0' implementation 'com.squareup.okhttp3:okhttp:3.12.0'
} }
#Mon Sep 03 21:51:40 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
...@@ -40,6 +40,7 @@ class FluwxPlugin(private val registrar: Registrar, channel: MethodChannel) : Me ...@@ -40,6 +40,7 @@ class FluwxPlugin(private val registrar: Registrar, channel: MethodChannel) : Me
private val fluwxPayHandler = FluwxPayHandler() private val fluwxPayHandler = FluwxPayHandler()
private val fluwxLaunchMiniProgramHandler = FluwxLaunchMiniProgramHandler() private val fluwxLaunchMiniProgramHandler = FluwxLaunchMiniProgramHandler()
private val fluwxSubscribeMsgHandler = FluwxSubscribeMsgHandler() private val fluwxSubscribeMsgHandler = FluwxSubscribeMsgHandler()
private val fluwxAutodeducthandler = FluwxAutoDeductHandler()
init { init {
fluwxShareHandler.setRegistrar(registrar) fluwxShareHandler.setRegistrar(registrar)
...@@ -98,6 +99,17 @@ class FluwxPlugin(private val registrar: Registrar, channel: MethodChannel) : Me ...@@ -98,6 +99,17 @@ class FluwxPlugin(private val registrar: Registrar, channel: MethodChannel) : Me
return return
} }
if (WeChatPluginMethods.AUTO_DEDUCT == call.method) {
fluwxAutodeducthandler.signAutoDeduct(call, result)
return
}
if ("openWXApp" == call.method){
val isSent = WXAPiHandler.wxApi?.openWXApp()?:false
result.success(isSent)
return
}
if (call.method.startsWith("share")) { if (call.method.startsWith("share")) {
fluwxShareHandler.handle(call, result) fluwxShareHandler.handle(call, result)
} else { } else {
......
...@@ -26,4 +26,6 @@ public class WeChatPluginMethods { ...@@ -26,4 +26,6 @@ public class WeChatPluginMethods {
public static final String WE_CHAT_PAY_RESPONSE = "onPayResponse"; public static final String WE_CHAT_PAY_RESPONSE = "onPayResponse";
public static final String SUBSCRIBE_MSG = "subscribeMsg"; public static final String SUBSCRIBE_MSG = "subscribeMsg";
public static final String AUTO_DEDUCT = "autoDeduct";
} }
package com.jarvan.fluwx.handler
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import java.util.HashMap
class FluwxAutoDeductHandler {
fun signAutoDeduct(call: MethodCall, result: MethodChannel.Result) {
val appId:String = call.argument<String>("appid") ?: ""
val mchId = call.argument<String>("mch_id") ?: ""
val planId = call.argument<String>("plan_id") ?: ""
val contractCode = call.argument<String>("contract_code") ?: ""
val requestSerial = call.argument<String>("request_serial") ?: ""
val contractDisplayAccount = call.argument<String>("contract_display_account") ?: ""
val notifyUrl = call.argument<String>("notify_url") ?: ""
val version = call.argument<String>("version") ?: ""
val sign = call.argument<String>("sign") ?: ""
val timestamp = call.argument<String>("timestamp") ?: ""
val returnApp = call.argument<String>("return_app") ?: ""
val businessType = call.argument<Int>("businessType")?:12
val map = HashMap<String,String>()
map["appid"] = appId
map["mch_id"] = mchId
map["plan_id"] = planId
map["contract_code"] = contractCode
map["request_serial"] = requestSerial
map["contract_display_account"] = contractDisplayAccount
map["notify_url"] = notifyUrl
map["version"] = version
map["sign"] = sign
map["timestamp"] = timestamp
map["return_app"] = returnApp
val req = WXOpenBusinessWebview.Req()
req.businessType = businessType
req.queryInfo = map
val b = WXAPiHandler.wxApi?.sendReq(req)
result.success(b)
}
}
\ No newline at end of file
...@@ -20,6 +20,7 @@ import com.jarvan.fluwx.constant.WechatPluginKeys ...@@ -20,6 +20,7 @@ import com.jarvan.fluwx.constant.WechatPluginKeys
import com.tencent.mm.opensdk.modelbase.BaseResp import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage import com.tencent.mm.opensdk.modelbiz.SubscribeMessage
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview
import com.tencent.mm.opensdk.modelmsg.SendAuth import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX import com.tencent.mm.opensdk.modelmsg.SendMessageToWX
import com.tencent.mm.opensdk.modelpay.PayResp import com.tencent.mm.opensdk.modelpay.PayResp
...@@ -46,6 +47,7 @@ object FluwxResponseHandler { ...@@ -46,6 +47,7 @@ object FluwxResponseHandler {
is PayResp -> handlePayResp(response) is PayResp -> handlePayResp(response)
is WXLaunchMiniProgram.Resp -> handleLaunchMiniProgramResponse(response) is WXLaunchMiniProgram.Resp -> handleLaunchMiniProgramResponse(response)
is SubscribeMessage.Resp -> handleSubscribeMessage(response) is SubscribeMessage.Resp -> handleSubscribeMessage(response)
is WXOpenBusinessWebview.Resp -> handlerWXOpenBusinessWebviewResponse(response)
} }
} }
...@@ -131,4 +133,20 @@ object FluwxResponseHandler { ...@@ -131,4 +133,20 @@ object FluwxResponseHandler {
} }
private fun handlerWXOpenBusinessWebviewResponse(response:WXOpenBusinessWebview.Resp){
val result = mapOf(
WechatPluginKeys.PLATFORM to WechatPluginKeys.ANDROID,
errCode to response.errCode,
"businessType" to response.businessType,
"resultInfo" to response.resultInfo,
errStr to response.errStr,
openId to response.openId,
type to response.type,
WechatPluginKeys.TRANSACTION to response.transaction
)
channel?.invokeMethod("onAutoDeductResponse", result)
}
} }
\ No newline at end of file
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.jarvan.fluwx.handler package com.jarvan.fluwx.handler
import android.util.Log
import com.jarvan.fluwx.constant.CallResult import com.jarvan.fluwx.constant.CallResult
import com.jarvan.fluwx.constant.WeChatPluginMethods import com.jarvan.fluwx.constant.WeChatPluginMethods
import com.jarvan.fluwx.constant.WechatPluginKeys import com.jarvan.fluwx.constant.WechatPluginKeys
...@@ -25,6 +26,7 @@ import io.flutter.plugin.common.MethodCall ...@@ -25,6 +26,7 @@ import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.ByteArrayInputStream
/*** /***
...@@ -55,11 +57,11 @@ internal class FluwxShareHandler { ...@@ -55,11 +57,11 @@ internal class FluwxShareHandler {
result.error(CallResult.RESULT_API_NULL, "please config wxapi first", null) result.error(CallResult.RESULT_API_NULL, "please config wxapi first", null)
return return
} }
//
if (!WXAPiHandler.wxApi!!.isWXAppInstalled) { // if (!WXAPiHandler.wxApi!!.isWXAppInstalled) {
result.error(CallResult.RESULT_WE_CHAT_NOT_INSTALLED, CallResult.RESULT_WE_CHAT_NOT_INSTALLED, null) // result.error(CallResult.RESULT_WE_CHAT_NOT_INSTALLED, CallResult.RESULT_WE_CHAT_NOT_INSTALLED, null)
return // return
} // }
when (call.method) { when (call.method) {
WeChatPluginMethods.SHARE_TEXT -> shareText(call, result) WeChatPluginMethods.SHARE_TEXT -> shareText(call, result)
...@@ -170,11 +172,31 @@ internal class FluwxShareHandler { ...@@ -170,11 +172,31 @@ internal class FluwxShareHandler {
val byteArray: ByteArray? = if (imagePath.isNullOrBlank()) { val byteArray: ByteArray? = if (imagePath.isNullOrBlank()) {
byteArrayOf() byteArrayOf()
} else { } else {
getImageByteArrayCommon(registrar, imagePath!!) getImageByteArrayCommon(registrar, imagePath)
} }
val imgObj = if (byteArray != null && byteArray.isNotEmpty()) { val imgObj = if (byteArray != null && byteArray.isNotEmpty()) {
if (byteArray.size > 512 * 1024){
val input = ByteArrayInputStream(byteArray)
val suffix = when {
imagePath.isNullOrBlank() -> ".jpeg"
imagePath.lastIndexOf(".") == -1 -> ".jpeg"
else -> imagePath.substring(imagePath.lastIndexOf("."))
}
val file = ShareImageUtil.inputStreamToFile(input,suffix,registrar!!.context())
WXImageObject().apply {
setImagePath(file.absolutePath)
}
}else{
WXImageObject(byteArray) WXImageObject(byteArray)
}
} else { } else {
null null
} }
......
...@@ -15,19 +15,24 @@ ...@@ -15,19 +15,24 @@
*/ */
package com.jarvan.fluwx.utils; package com.jarvan.fluwx.utils;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.res.AssetFileDescriptor; import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.MediaStore;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.jarvan.fluwx.constant.WeChatPluginImageSchema; import com.jarvan.fluwx.constant.WeChatPluginImageSchema;
import com.jarvan.fluwx.constant.WechatPluginKeys; import com.jarvan.fluwx.constant.WechatPluginKeys;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
...@@ -50,7 +55,7 @@ public class ShareImageUtil { ...@@ -50,7 +55,7 @@ public class ShareImageUtil {
public static byte[] getImageData(PluginRegistry.Registrar registrar, String path) { public static byte[] getImageData(PluginRegistry.Registrar registrar, String path) {
byte[] result = null; byte[] result = null;
if (path.startsWith(WeChatPluginImageSchema.SCHEMA_ASSETS)) { if (path.startsWith(WeChatPluginImageSchema.SCHEMA_ASSETS)) {
String key = path.substring(WeChatPluginImageSchema.SCHEMA_ASSETS.length(), path.length()); String key = path.substring(WeChatPluginImageSchema.SCHEMA_ASSETS.length());
AssetFileDescriptor fileDescriptor = AssetManagerUtil.openAsset(registrar, key, getPackage(key)); AssetFileDescriptor fileDescriptor = AssetManagerUtil.openAsset(registrar, key, getPackage(key));
try { try {
InputStream inputStream = fileDescriptor.createInputStream(); InputStream inputStream = fileDescriptor.createInputStream();
...@@ -118,14 +123,23 @@ public class ShareImageUtil { ...@@ -118,14 +123,23 @@ public class ShareImageUtil {
return packageStr; return packageStr;
} }
private static File inputStreamToTmpFile(InputStream inputStream, String suffix) { public static File inputStreamToFile(InputStream inputStream, String suffix, Context context) {
File file = null; File file = null;
BufferedSink sink = null; BufferedSink sink = null;
Source source = null; Source source = null;
OutputStream outputStream = null; OutputStream outputStream = null;
try { try {
file = File.createTempFile(UUID.randomUUID().toString(), suffix);
File externalFile = context.getExternalCacheDir();
if (externalFile == null) {
return null;
}
file = new File(externalFile.getAbsolutePath()+File.separator+UUID.randomUUID().toString()+suffix);
// file = File.createTempFile(UUID.randomUUID().toString(), suffix);
outputStream = new FileOutputStream(file); outputStream = new FileOutputStream(file);
sink = Okio.buffer(Okio.sink(outputStream)); sink = Okio.buffer(Okio.sink(outputStream));
source = Okio.source(inputStream); source = Okio.source(inputStream);
...@@ -162,7 +176,13 @@ public class ShareImageUtil { ...@@ -162,7 +176,13 @@ public class ShareImageUtil {
return file; return file;
} }
private static InputStream openStream(String url) { private static InputStream openStream(String url) {
if(!url.startsWith("https") && !url.startsWith("http")){
url = "http://"+url;
}
OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(url).get().build(); Request request = new Request.Builder().url(url).get().build();
try { try {
......
...@@ -224,6 +224,11 @@ public class WeChatThumbnailUtil { ...@@ -224,6 +224,11 @@ public class WeChatThumbnailUtil {
} }
private static File downloadImage(String url) { private static File downloadImage(String url) {
if(!url.startsWith("https") && !url.startsWith("http")){
url = "http://"+url;
}
File result = null; File result = null;
OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(url).get().build(); Request request = new Request.Builder().url(url).get().build();
......
## SIGN AUTO-DEDUCT
see [details](https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_5&index=2).
```dart
import 'package:fluwx/fluwx.dart' as fluwx;
fluwx.autoDeDuct(
appId: "",
mchId: "",
planId: "",
contractCode: "",
requestSerial: "",
contractDisplayAccount: "",
notifyUrl: "",
version: "",
sign: "",
timestamp: "",
returnApp: '3');
```
\ No newline at end of file
## 签约微信免密支付
查看 [详情](https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_5&index=2).
```dart
import 'package:fluwx/fluwx.dart' as fluwx;
fluwx.autoDeDuct(
appId: "",
mchId: "",
planId: "",
contractCode: "",
requestSerial: "",
contractDisplayAccount: "",
notifyUrl: "",
version: "",
sign: "",
timestamp: "",
returnApp: '3');
```
\ No newline at end of file
...@@ -19,3 +19,119 @@ Check your signature please. ...@@ -19,3 +19,119 @@ Check your signature please.
## Failed to notify project evalution listener ## Failed to notify project evalution listener
[Failed to notify project evalution listener](https://www.jianshu.com/p/f74fed94be96) [Failed to notify project evalution listener](https://www.jianshu.com/p/f74fed94be96)
## Can't receive response after upgrading to 1.0.0 on iOS
There's no need to override `AppDelegate` since `fluwx 1.0.0`. If you have did thad before, please remove
the following code in your `AppDelegate`:
```objective-c
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
```
If you have to override these two functions,make sure you have called the `super`:
```objective-c
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [super application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
return [super application:application openURL:url options:options];
}
```
**!!!!请先看[文档](https://github.com/OpenFlutter/fluwx/blob/master/README_CN.md),再看常见Q&A,再查看issue,自我排查错误,方便你我他。依然无法解决的问题可以加群提问, QQ Group:892398530。!!!!**
## 常见Q&A
#### Fluwx调起失败?
请检查APPID、包名、以及App签名是否一致。debug 和release的签名默认不一样,请注意。
#### Android Flutter编译失败
1、检查Kotlin版本,打开```build.gradle```文件,查看以下配置
```
buildscript {
······
ext.kotlin_version = '1.3.11'
······
}
```
确保项目中使用的Kotlin版本符合要求;
2、检查Android目录下```build.gradle```文件中gradle插件版本:```classpath 'com.android.tools.build:gradle:3.2.1'``````gradle-wrapper.properties```文件中的gradle版本是否匹配:```distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip```,两者的匹配规则见Android官网:[Update Gradle](https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle)
#### WeChat Not Installed on iOS?
iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
受此影响,当你的应用在iOS 9中需要使用微信SDK的相关能力(分享、收藏、支付、登录等)时,需要在“Info.plist”里增加如下代码:
```xml
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
```
#### 如果没有安装微信,微信登录不了,导致iOS审核失败
fluwx提供了检查用户是否安装微信的方法:```isWeChatInstalled()```,iOS使用微信相关功能前,务必先检查微信是否安装。
#### Failed to notify project evalution listener
[Failed to notify project evalution listener](https://www.jianshu.com/p/f74fed94be96)
#### 微信登录不能触发fluwx.responseFromAuth.listen监听回调
请先看文档:[微信调回](https://github.com/OpenFlutter/fluwx/blob/master/doc/RESPONSE_CN.md) 。Android端如果是混合开发,请注册```WXEntryActivity```and```WXPayEntryActivity```;iOS端请重写```AppDelegate```中的相关方法。
#### isWeChatInstalled返回false
请查看该 [issue](https://github.com/OpenFlutter/fluwx/issues/34) ,检查```AppDelegate```中配置是否正确。
#### Kotlin报错:XXX is only available since Kotlin 1.3 and cannot be used in Kotlin 1.2
1、请检查IDE安装的Kotlin插件版本是否符合fluwx要求:AS打开设置-->Plugin-->Koltin查看插件版本;
2、请检查项目中使用的Kotlin版本:打开```build.gradle```文件,查看以下配置
```
buildscript {
······
ext.kotlin_version = '1.3.11'
······
}
```
#### listen监听多次调用
请查看该 [issue](https://github.com/OpenFlutter/fluwx/issues/36) 。这个问题是由于listen被多次注册导致的,使用者自己代码的问题,非fluwx导致的,请在合适的时机将listen cancel掉:
```
StreamSubscription<WeChatAuthResponse> _wxlogin;
_wxlogin = fluwx.responseFromAuth.listen((val) {})
@override
void dispose() {
_wxlogin.cancel();
}
```
#### 分享完成或者取消分享后App崩溃
如果你手动注册了```WXEntryActivity```and```WXPayEntryActivity```,请检查```Manifest```中包名是否写对了。
#### IOS编译错误:No such module 'fluwx'
如果项目本身是在Android环境配置的,移到iOS的环境的时候,会出现该问题,请按照正常步骤配置。
#### 支付成功后,按物理按键或手机自动返回商户APP,监听不到返回数据
有人反应会出现```fluwx.responseFromPayment.listen```监听无效,无法获取支付结果,建议可以直接向服务器查询是否成功。
#### iOS报错:Specs satisfying the `fluwx (from `.symlinks/plugins/fluwx/ios`)` dependency were found, but they required a higher minimum deployment target.
请在在pod file里将iOS项目deployment target改到9.0。
#### ResponseType与Dio插件中的命名冲突
使用as的方式导包即可:```import 'package:fluwx/fluwx.dart' as fluwx;```
...@@ -59,7 +59,9 @@ xml ...@@ -59,7 +59,9 @@ xml
</dict> </dict>
``` ```
### iOS上升级到1.0.0 后无法接收回调
#### iOS上升级到1.0.0 后无法接收回调
`fluwx 1.0.0`开始开发者不必重写`AppDelegate`了。如果你以前重写了这个方法,请在 `AppDelegate`中删除相应的代码: `fluwx 1.0.0`开始开发者不必重写`AppDelegate`了。如果你以前重写了这个方法,请在 `AppDelegate`中删除相应的代码:
...@@ -88,7 +90,9 @@ xml ...@@ -88,7 +90,9 @@ xml
} }
``` ```
### 没有安装微信,微信登录不了,导致iOS审核失败
#### 如果没有安装微信,微信登录不了,导致iOS审核失败
fluwx提供了检查用户是否安装微信的方法:```isWeChatInstalled()```,iOS使用微信相关功能前,务必先检查微信是否安装。 fluwx提供了检查用户是否安装微信的方法:```isWeChatInstalled()```,iOS使用微信相关功能前,务必先检查微信是否安装。
### Failed to notify project evalution listener ### Failed to notify project evalution listener
......
### Response From WeChat ### Response From WeChat
There's some work we have to do on the particular platform(if you don't need this,just ignore). There's some work we have to do on the particular platform(if you don't need this,just ignore).
### Flutter
We can get the reponse from WeChat after sharing and etc:
```dart
fluwx.responseFromShare.listen((response){
//do something
});
fluwx.responseFromAuth.listen((response){
//do something
});
fluwx.responseFromPayment.listen((response){
//do something
});
```
> NOTE:If the field starts with "android" or "iOS", it means that only android or iOS has the field.
The type of return value is `WeChatResponse`,and `type` is an enum:
```dart
enum WeChatResponseType {
SHARE,
AUTH,
PAYMENT }
```
### Android ### Android
Fluwx will create `WXEntryActivity`or`WXPayEntryActivity` by itself since *0.4.0*. So the following Fluwx will create `WXEntryActivity`or`WXPayEntryActivity` by itself since *0.4.0*. So the following
code isn't necessary. code isn't necessary.
...@@ -84,7 +113,8 @@ can inherit `FluwxWXEntryActivity` for convenience.Then register `WXEntryActivit ...@@ -84,7 +113,8 @@ can inherit `FluwxWXEntryActivity` for convenience.Then register `WXEntryActivit
``` ```
### iOS ### iOS
override the following function in`AppDelegate`: don't override this since 1.0.0:
~~override the following function in`AppDelegate`:~~
```objective-c ```objective-c
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]]; return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
...@@ -99,27 +129,4 @@ override the following function in`AppDelegate`: ...@@ -99,27 +129,4 @@ override the following function in`AppDelegate`:
> NOTE:Don't forget to add URL Schema in order to go back to your app. > NOTE:Don't forget to add URL Schema in order to go back to your app.
### Flutter
We can get the reponse from WeChat after sharing and etc:
```dart
fluwx.responseFromShare.listen((response){
//do something
});
fluwx.responseFromAuth.listen((response){
//do something
});
fluwx.responseFromPayment.listen((response){
//do something
});
```
> NOTE:If the field starts with "android" or "iOS", it means that only android or iOS has the field.
The type of return value is `WeChatResponse`,and `type` is an enum:
```dart
enum WeChatResponseType {
SHARE,
AUTH,
PAYMENT }
```
`result` is the real response from WeChat,it's a `Map`, read the WeChat documents for more details.
Howver,there an addtional param `platform`,the value of `platform` is `android`or`iOS`.
### 微信调回 ### 微信调回
微信的回调也要根据平台的不同进行差异化处理(如果你不需要回调,请忽略)。 微信的回调也要根据平台的不同进行差异化处理(如果你不需要回调,请忽略)。
### Flutter
```dart
fluwx.responseFromShare.listen((response){
//do something
});
fluwx.responseFromAuth.listen((response){
//do something
});
fluwx.responseFromPayment.listen((response){
//do something
});
```
> 注意:如果一个字段以*android*或者*iOS*开头,那么意味这个字段只存在于*android*或者*iOS*。
### Android ### Android
*0.4.0*开始,开发者不必手动添加`WXEntryActivity``WXPayEntryActivity`了,所以下面的不是必需要的了: *0.4.0*开始,开发者不必手动添加`WXEntryActivity``WXPayEntryActivity`了,所以下面的不是必需要的了:
~~由于机制问题,`Android`端需要在`WXEntryActivity``WXPayEntryActivity`中添加如下代码:~~ ~~由于机制问题,`Android`端需要在`WXEntryActivity``WXPayEntryActivity`中添加如下代码:~~
...@@ -83,7 +101,8 @@ ...@@ -83,7 +101,8 @@
``` ```
### iOS ### iOS
在你的`AppDelegate`中重写下面方法: 从1.0.0开始以下作废
~~在你的`AppDelegate`中重写下面方法~~:
```objective-c ```objective-c
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]]; return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
...@@ -96,18 +115,3 @@ ...@@ -96,18 +115,3 @@
``` ```
> 注意:为了能够返回你的app,请不要忘记添加URL Schema。 > 注意:为了能够返回你的app,请不要忘记添加URL Schema。
### Flutter
```dart
fluwx.responseFromShare.listen((response){
//do something
});
fluwx.responseFromAuth.listen((response){
//do something
});
fluwx.responseFromPayment.listen((response){
//do something
});
```
> 注意:如果一个字段以*android*或者*iOS*开头,那么意味这个字段只存在于*android*或者*iOS*。
...@@ -57,6 +57,7 @@ However, developers must care about the following points: ...@@ -57,6 +57,7 @@ However, developers must care about the following points:
)); ));
``` ```
## Share Image ## Share Image
```dart ```dart
fluwx.share(WeChatShareImageModel( fluwx.share(WeChatShareImageModel(
image: _imagePath, image: _imagePath,
...@@ -67,6 +68,19 @@ However, developers must care about the following points: ...@@ -67,6 +68,19 @@ However, developers must care about the following points:
``` ```
> NOTE:`Fluwx` will create thumbnail from `image` if thumbnail isn't provided. > NOTE:`Fluwx` will create thumbnail from `image` if thumbnail isn't provided.
Well,let's talk about sharing big images on Android,if the image you want to share is smaller than 512k (the truth is the data passed through
`Intent` must be smaller than 512k), everything works well.However, if it's bigger than
512k, take care the following permission:
```xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```
`Fluwx` can't share big images without the permission above because these images will stored in:
```kotlin
context.getExternalCacheDir()
```
Why? Because the limit of `Intent`. If someone knows a better solution,just PR or tell me.
## Share Music ## Share Music
```dart ```dart
var model = WeChatShareMusicModel( var model = WeChatShareMusicModel(
...@@ -83,7 +97,7 @@ Two kind of music:`musicUrl`和`musicLowBandUrl`.They are not coexisting,if ...@@ -83,7 +97,7 @@ Two kind of music:`musicUrl`和`musicLowBandUrl`.They are not coexisting,if
## Share Video ## Share Video
```dart ```dart
var model = new WeChatShareVideoModel( var model = fluwx.WeChatShareVideoModel(
videoUrl: _videoUrl, videoUrl: _videoUrl,
transaction: "video", transaction: "video",
videoLowBandUrl: _videoLowBandUrl, videoLowBandUrl: _videoLowBandUrl,
...@@ -97,7 +111,7 @@ Two kind of video:`videoUrl`和`videoLowBandUrl`.They are not coexisting,if bo ...@@ -97,7 +111,7 @@ Two kind of video:`videoUrl`和`videoLowBandUrl`.They are not coexisting,if bo
## Share Mini Program ## Share Mini Program
```dart ```dart
var model =new WeChatShareMiniProgramModel( var model = fluwx.WeChatShareMiniProgramModel(
webPageUrl: _webPageUrl, webPageUrl: _webPageUrl,
miniProgramType:fluwx.WXMiniProgramType.RELEASE, miniProgramType:fluwx.WXMiniProgramType.RELEASE,
userName: _userName, userName: _userName,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
## 分享文本 ## 分享文本
```dart ```dart
fluwx.share(WeChatShareTextModel( fluwx.share(fluwx.WeChatShareTextModel(
text: "text from fluwx", text: "text from fluwx",
transaction: "transaction}",//仅在android上有效,下同。 transaction: "transaction}",//仅在android上有效,下同。
scene: scene scene: scene
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
## 分享图片 ## 分享图片
```dart ```dart
fluwx.share(WeChatShareImageModel( fluwx.share(fluwx.WeChatShareImageModel(
image: _imagePath, image: _imagePath,
thumbnail: _thumbnail, thumbnail: _thumbnail,
transaction: _imagePath, transaction: _imagePath,
...@@ -57,10 +57,24 @@ ...@@ -57,10 +57,24 @@
> 注意:如果不指定 `thumbnail`,那么`Fluwx`将尝试从`image`中获取缩略图。 > 注意:如果不指定 `thumbnail`,那么`Fluwx`将尝试从`image`中获取缩略图。
好吧,让我们谈谈在Android上分享大图,如果说你要分享的图片小于512k(实际上是因为`Intent`传值是不能超过512k的),一切都可以正常工作。
但是如果你要分享的图片大于512k,那么请保证你的app有以下的权限:
```xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```
如果`Fluwx`没有以上的权限,那么是无法完成分享的,因为要分享的图片将会被存储在以下位置:
```kotlin
context.getExternalCacheDir()
```
为什么? 因为`Intent`有限制. 如果有人知道更好的解决方案,请直接PR或者告诉我。
## 分享音乐 ## 分享音乐
```dart ```dart
var model = WeChatShareMusicModel( var model = fluwx.WeChatShareMusicModel(
title: _title, title: _title,
description: _description, description: _description,
transaction: "music", transaction: "music",
...@@ -77,7 +91,7 @@ ...@@ -77,7 +91,7 @@
## 分享视频 ## 分享视频
```dart ```dart
var model = new WeChatShareVideoModel( var model = fluwx.WeChatShareVideoModel(
videoUrl: _videoUrl, videoUrl: _videoUrl,
transaction: "video", transaction: "video",
videoLowBandUrl: _videoLowBandUrl, videoLowBandUrl: _videoLowBandUrl,
...@@ -94,7 +108,7 @@ ...@@ -94,7 +108,7 @@
### 分享小程序 ### 分享小程序
```dart ```dart
var model =new WeChatShareMiniProgramModel( var model = fluwx.WeChatShareMiniProgramModel(
webPageUrl: _webPageUrl, webPageUrl: _webPageUrl,
miniProgramType: fluwx.WXMiniProgramType.RELEASE, miniProgramType: fluwx.WXMiniProgramType.RELEASE,
userName: _userName, userName: _userName,
......
...@@ -26,5 +26,5 @@ The return value of `fluwx.share(model)` is a `Map`: ...@@ -26,5 +26,5 @@ The return value of `fluwx.share(model)` is a `Map`:
result:true //or false,depends on WXApi.sendRequest() result:true //or false,depends on WXApi.sendRequest()
} }
``` ```
For the response from WeChat,read [RESPONSE](./doc/RESPONSE.md) please. For the response from WeChat,read [RESPONSE](./RESPONSE.md) please.
buildscript { buildscript {
ext.kotlin_version = '1.3.21' ext.kotlin_version = '1.3.31'
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.2' classpath 'com.android.tools.build:gradle:3.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
......
#Fri Apr 19 09:29:07 CST 2019
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
...@@ -19,4 +19,4 @@ SPEC CHECKSUMS: ...@@ -19,4 +19,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 348e15598a1c6ea25d3ed63919d5ffb9bd1c2ba6 PODFILE CHECKSUM: 348e15598a1c6ea25d3ed63919d5ffb9bd1c2ba6
COCOAPODS: 1.6.1 COCOAPODS: 1.7.2
...@@ -197,6 +197,7 @@ ...@@ -197,6 +197,7 @@
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
English,
en, en,
Base, Base,
); );
...@@ -450,7 +451,7 @@ ...@@ -450,7 +451,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.jarvanmo.fluwx-example3"; PRODUCT_BUNDLE_IDENTIFIER = com.jarvanmo.fluwxexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
USER_HEADER_SEARCH_PATHS = "\"${PROJECT_DIR}/../..\"/** \"${PROJECT_DIR}/../..\"/**"; USER_HEADER_SEARCH_PATHS = "\"${PROJECT_DIR}/../..\"/** \"${PROJECT_DIR}/../..\"/**";
...@@ -478,7 +479,7 @@ ...@@ -478,7 +479,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
PRODUCT_BUNDLE_IDENTIFIER = "com.jarvanmo.fluwx-example3"; PRODUCT_BUNDLE_IDENTIFIER = com.jarvanmo.fluwxexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
USER_HEADER_SEARCH_PATHS = "\"${PROJECT_DIR}/../..\"/** \"${PROJECT_DIR}/../..\"/**"; USER_HEADER_SEARCH_PATHS = "\"${PROJECT_DIR}/../..\"/** \"${PROJECT_DIR}/../..\"/**";
......
...@@ -17,16 +17,16 @@ ...@@ -17,16 +17,16 @@
// return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]]; // return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
//} //}
// //
//
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]]; //- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
} // [super application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
// return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
//}
//- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
//{
// [super application:app openURL:url options:options];
// return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
//}
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Fluwx</string> <string>FluwxDemo</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
......
import UIKit
import Flutter
import fluwx
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return WXApi.handleOpen(url, delegate: FluwxResponseHandler.defaultManager())
}
// NOTE: 9.0以后使用新API接口
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return WXApi.handleOpen(url, delegate: FluwxResponseHandler.defaultManager())
}
}
//
// Generated file. Do not edit.
//
#ifndef GeneratedPluginRegistrant_h
#define GeneratedPluginRegistrant_h
#import <Flutter/Flutter.h>
@interface GeneratedPluginRegistrant : NSObject
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
@end
#endif /* GeneratedPluginRegistrant_h */
//
// Generated file. Do not edit.
//
#import "GeneratedPluginRegistrant.h"
#import <fluwx/FluwxPlugin.h>
@implementation GeneratedPluginRegistrant
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[FluwxPlugin registerWithRegistrar:[registry registrarForPlugin:@"FluwxPlugin"]];
}
@end
#import "GeneratedPluginRegistrant.h"
...@@ -2,8 +2,9 @@ import 'dart:async'; ...@@ -2,8 +2,9 @@ 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 'launch_mini_program_page.dart';
import 'subscribe_message_page.dart';
import 'auth_by_qr_code_page.dart'; import 'auth_by_qr_code_page.dart';
import 'pay_page.dart'; import 'pay_page.dart';
...@@ -14,6 +15,7 @@ import 'share_music.dart'; ...@@ -14,6 +15,7 @@ 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 'sign_auto_deduct_page.dart';
void main() => runApp(new MyApp()); void main() => runApp(new MyApp());
...@@ -56,7 +58,8 @@ class _MyAppState extends State<MyApp> { ...@@ -56,7 +58,8 @@ 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() "AuthByQRCode": (ctx) => AuthByQRCodePage(),
'AutoDeduct': (ctx) => SignAutoDeductPage(),
}, },
home: new Scaffold( home: new Scaffold(
appBar: new AppBar( appBar: new AppBar(
...@@ -161,6 +164,22 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -161,6 +164,22 @@ class ShareSelectorPage extends StatelessWidget {
}, },
child: const Text("AuthByQRCode")), child: const Text("AuthByQRCode")),
), ),
Padding(
padding: const EdgeInsets.all(8.0),
child: new OutlineButton(
onPressed: () {
Navigator.of(context).pushNamed("AutoDeduct");
},
child: const Text("SignAuto-deduct")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: new OutlineButton(
onPressed: () {
fluwx.openWeChatApp();
},
child: const Text("Open WeChat App")),
),
], ],
), ),
); );
......
...@@ -18,6 +18,7 @@ class _PayPageState extends State<PayPage> { ...@@ -18,6 +18,7 @@ class _PayPageState extends State<PayPage> {
void initState() { void initState() {
super.initState(); super.initState();
fluwx.responseFromPayment.listen((data) { fluwx.responseFromPayment.listen((data) {
setState(() { setState(() {
_result = "${data.errCode}"; _result = "${data.errCode}";
......
...@@ -9,8 +9,9 @@ class ShareImagePage extends StatefulWidget { ...@@ -9,8 +9,9 @@ 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 =
// "http://img-download.pchome.net/download/1k1/3a/3e/ofskcd-s1a.jpg"
"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://images/logo.png";
String _response = ""; String _response = "";
...@@ -54,7 +55,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -54,7 +55,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
), ),
TextField( TextField(
decoration: InputDecoration(labelText: "缩略地址"), decoration: InputDecoration(labelText: "缩略地址"),
controller: TextEditingController(text: "assets://logo.png"), controller: TextEditingController(text: "assets://images/logo.png"),
onChanged: (value) { onChanged: (value) {
_thumbnail = value; _thumbnail = value;
}, },
......
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:fluwx/fluwx.dart' as fluwx;
class SignAutoDeductPage extends StatefulWidget {
@override
_SignAutoDeductPageState createState() => _SignAutoDeductPageState();
}
/// see wechat [document](https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_5&index=2)
class _SignAutoDeductPageState extends State<SignAutoDeductPage> {
TextEditingController appId =
TextEditingController(text: "wx316f9c82e99ac105");
TextEditingController mchId = TextEditingController(text: "");
TextEditingController planId = TextEditingController(text: "");
TextEditingController contractCode = TextEditingController(text: "");
TextEditingController requestSerial = TextEditingController(text: "");
TextEditingController contractDisplayAccount =
TextEditingController(text: "");
TextEditingController notifyUrl = TextEditingController(text: "");
TextEditingController version = TextEditingController(text: "1.0");
TextEditingController sign = TextEditingController(text: "");
TextEditingController timestamp = TextEditingController(text: "");
TextEditingController returnApp = TextEditingController(text: "3");
@override
void initState() {
super.initState();
fluwx.responseFromSubscribeMsg.listen((resp) {
print("resp = $resp");
});
}
@override
void dispose() {
appId.dispose();
mchId.dispose();
planId.dispose();
contractCode.dispose();
contractDisplayAccount.dispose();
requestSerial.dispose();
notifyUrl.dispose();
version.dispose();
sign.dispose();
timestamp.dispose();
returnApp.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SubscribeMessagePage'),
),
body: Container(
child: ListView(
children: <Widget>[
_buildTextField(title: "appId", textEditController: appId),
_buildTextField(title: "mchId", textEditController: mchId),
_buildTextField(title: "planId", textEditController: planId),
_buildTextField(
title: "contractCode", textEditController: contractCode),
_buildTextField(
title: "requestSerial", textEditController: requestSerial),
_buildTextField(
title: "contractDisplayAccount",
textEditController: contractDisplayAccount),
_buildTextField(title: "notifyUrl", textEditController: notifyUrl),
_buildTextField(title: "version", textEditController: version),
_buildTextField(title: "sign", textEditController: sign),
_buildTextField(title: "timestamp", textEditController: timestamp),
_buildTextField(title: "returnApp", textEditController: returnApp),
CupertinoButton(
child: Text('request once sign auto-deduct message'),
onPressed: _signAutoDeduct,
),
],
),
),
);
}
Widget _buildTextField({
String title,
TextEditingController textEditController,
}) {
return TextField(
decoration: InputDecoration(
labelText: title,
),
controller: textEditController,
);
}
void _signAutoDeduct() {
fluwx.autoDeDuct(
appId: appId.text ?? "",
mchId: mchId.text ?? "",
planId: planId.text ?? "",
contractCode: contractCode.text ?? "",
requestSerial: requestSerial.text ?? "",
contractDisplayAccount: contractDisplayAccount.text ?? "",
notifyUrl: notifyUrl.text ?? "",
version: version.text ?? "",
sign: sign.text ?? "",
timestamp: timestamp.text ?? "",
returnApp: '3');
}
}
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#import "FluwxShareHandler.h" #import "FluwxShareHandler.h"
#import "FluwxLaunchMiniProgramHandler.h" #import "FluwxLaunchMiniProgramHandler.h"
#import "FluwxSubscribeMsgHandler.h" #import "FluwxSubscribeMsgHandler.h"
#import "FluwxAutoDeductHandler.h"
@implementation FluwxPlugin @implementation FluwxPlugin
...@@ -23,9 +24,9 @@ FluwxWXApiHandler *_fluwxWXApiHandler; ...@@ -23,9 +24,9 @@ FluwxWXApiHandler *_fluwxWXApiHandler;
FluwxPaymentHandler *_fluwxPaymentHandler; FluwxPaymentHandler *_fluwxPaymentHandler;
FluwxLaunchMiniProgramHandler *_fluwxLaunchMiniProgramHandler; FluwxLaunchMiniProgramHandler *_fluwxLaunchMiniProgramHandler;
FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler; FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler;
FluwxAutoDeductHandler *_fluwxAutoDeductHandler;
- (void)dealloc - (void)dealloc {
{
// [[NSNotificationCenter defaultCenter] removeObserver:self]; // [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
...@@ -37,7 +38,7 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler; ...@@ -37,7 +38,7 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler;
FluwxPlugin *instance = [[FluwxPlugin alloc] initWithRegistrar:registrar methodChannel:channel]; FluwxPlugin *instance = [[FluwxPlugin alloc] initWithRegistrar:registrar methodChannel:channel];
[[FluwxResponseHandler defaultManager] setMethodChannel:channel]; [[FluwxResponseHandler defaultManager] setMethodChannel:channel];
[registrar addMethodCallDelegate:instance channel:channel]; [registrar addMethodCallDelegate:instance channel:channel];
[registrar addApplicationDelegate:instance];
} }
...@@ -49,19 +50,18 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler; ...@@ -49,19 +50,18 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler;
// object:nil]; // object:nil];
if (self) { if (self) {
_fluwxShareHandler = [[FluwxShareHandler alloc] initWithRegistrar:registrar]; _fluwxShareHandler = [[FluwxShareHandler alloc] initWithRegistrar:registrar];
_fluwxAuthHandler = [[FluwxAuthHandler alloc] initWithRegistrar:registrar methodChannel:flutterMethodChannel] ; _fluwxAuthHandler = [[FluwxAuthHandler alloc] initWithRegistrar:registrar methodChannel:flutterMethodChannel];
_fluwxWXApiHandler = [[FluwxWXApiHandler alloc] init]; _fluwxWXApiHandler = [[FluwxWXApiHandler alloc] init];
_fluwxPaymentHandler = [[FluwxPaymentHandler alloc] initWithRegistrar:registrar]; _fluwxPaymentHandler = [[FluwxPaymentHandler alloc] initWithRegistrar:registrar];
_fluwxLaunchMiniProgramHandler = [[FluwxLaunchMiniProgramHandler alloc] initWithRegistrar:registrar]; _fluwxLaunchMiniProgramHandler = [[FluwxLaunchMiniProgramHandler alloc] initWithRegistrar:registrar];
_fluwxSubscribeMsgHandler = [[FluwxSubscribeMsgHandler alloc] initWithRegistrar:registrar]; _fluwxSubscribeMsgHandler = [[FluwxSubscribeMsgHandler alloc] initWithRegistrar:registrar];
_fluwxAutoDeductHandler = [[FluwxAutoDeductHandler alloc] initWithRegistrar:registrar];
} }
return self; return self;
} }
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
...@@ -70,42 +70,51 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler; ...@@ -70,42 +70,51 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler;
return; return;
} }
if([@"isWeChatInstalled" isEqualToString :call.method]){ if ([@"isWeChatInstalled" isEqualToString:call.method]) {
[_fluwxWXApiHandler checkWeChatInstallation:call result:result]; [_fluwxWXApiHandler checkWeChatInstallation:call result:result];
return; return;
} }
if([@"sendAuth" isEqualToString :call.method]){ if ([@"sendAuth" isEqualToString:call.method]) {
[_fluwxAuthHandler handleAuth:call result:result]; [_fluwxAuthHandler handleAuth:call result:result];
return; return;
} }
if([@"payWithFluwx" isEqualToString :call.method]){ if ([@"payWithFluwx" isEqualToString:call.method]) {
[_fluwxPaymentHandler handlePayment:call result:result]; [_fluwxPaymentHandler handlePayment:call result:result];
return; return;
} }
if([@"launchMiniProgram" isEqualToString :call.method]){ if ([@"launchMiniProgram" isEqualToString:call.method]) {
[_fluwxLaunchMiniProgramHandler handleLaunchMiniProgram:call result:result]; [_fluwxLaunchMiniProgramHandler handleLaunchMiniProgram:call result:result];
return; return;
} }
if([@"subscribeMsg" isEqualToString: call.method]){ if ([@"subscribeMsg" isEqualToString:call.method]) {
[_fluwxSubscribeMsgHandler handleSubscribeWithCall:call result:result]; [_fluwxSubscribeMsgHandler handleSubscribeWithCall:call result:result];
return; return;
} }
if([@"authByQRCode" isEqualToString:call.method]){ if ([@"authByQRCode" isEqualToString:call.method]) {
[_fluwxAuthHandler authByQRCode:call result:result]; [_fluwxAuthHandler authByQRCode:call result:result];
return; return;
} }
if([@"stopAuthByQRCode" isEqualToString:call.method]){ if ([@"stopAuthByQRCode" isEqualToString:call.method]) {
[_fluwxAuthHandler stopAuthByQRCode:call result:result]; [_fluwxAuthHandler stopAuthByQRCode:call result:result];
return; return;
} }
if ([@"autoDeduct" isEqualToString:call.method]) {
[_fluwxAutoDeductHandler handleAutoDeductWithCall:call result:result];
return;
}
if ([@"openWXApp" isEqualToString:call.method]) {
result(@([WXApi openWXApp]));
return;
}
if ([call.method hasPrefix:@"share"]) { if ([call.method hasPrefix:@"share"]) {
[_fluwxShareHandler handleShare:call result:result]; [_fluwxShareHandler handleShare:call result:result];
return; return;
...@@ -116,14 +125,23 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler; ...@@ -116,14 +125,23 @@ FluwxSubscribeMsgHandler *_fluwxSubscribeMsgHandler;
} }
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options {
return [WXApi handleOpenURL:url delegate:[FluwxResponseHandler defaultManager]];
}
-(BOOL)handleOpenURL:(NSNotification *)aNotification { - (BOOL)handleOpenURL:(NSNotification *)aNotification {
if(handleOpenURLByFluwx){ if (handleOpenURLByFluwx) {
NSString * aURLString = [aNotification userInfo][@"url"]; NSString *aURLString = [aNotification userInfo][@"url"];
NSURL * aURL = [NSURL URLWithString:aURLString]; NSURL *aURL = [NSURL URLWithString:aURLString];
return [WXApi handleOpenURL:aURL delegate:[FluwxResponseHandler defaultManager]]; return [WXApi handleOpenURL:aURL delegate:[FluwxResponseHandler defaultManager]];
} else{ } else {
return NO; return NO;
} }
......
//
// FluwxAutoDeductHandler.m
// fluwx
//
// Created by realm on 2019/5/22.
//
#import "FluwxAutoDeductHandler.h"
#import <WXApiRequestHandler.h>
@implementation FluwxAutoDeductHandler {
NSObject <FlutterPluginRegistrar> *_registrar;
}
- (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_registrar = registrar;
}
return self;
}
-(void)handleAutoDeductWithCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSDictionary *params = call.arguments;
NSMutableDictionary *paramsFromDart = [NSMutableDictionary dictionaryWithDictionary:call.arguments];
[paramsFromDart removeObjectForKey:@"businessType"];
WXOpenBusinessWebViewReq *req = [[WXOpenBusinessWebViewReq alloc] init];
NSNumber * businessType = call.arguments[@"businessType"];
req.businessType = [businessType unsignedIntValue];
req.queryInfoDic = paramsFromDart;
BOOL b = [WXApi sendReq:req];
result(@(b));
}
-(NSString *)convertToJsonData:(NSDictionary *)dict
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString;
if (!jsonData) {
NSLog(@"%@",error);
}else{
jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
// NSRange range = {0,jsonString.length};
// //去掉字符串中的空格
// [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
//去掉字符串中的换行符
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
return mutStr;
}
@end
...@@ -26,10 +26,7 @@ ...@@ -26,10 +26,7 @@
return; return;
} }
if (![WXApi isWXAppInstalled]) {
result([FlutterError errorWithCode:@"wechat not installed" message:@"wechat not installed" details:nil]);
return;
}
NSNumber * timestamp = call.arguments[@"timeStamp"]; NSNumber * timestamp = call.arguments[@"timeStamp"];
......
...@@ -37,11 +37,11 @@ NSObject <FlutterPluginRegistrar> *_registrar; ...@@ -37,11 +37,11 @@ NSObject <FlutterPluginRegistrar> *_registrar;
result([FlutterError errorWithCode:resultErrorNeedWeChat message:resultMessageNeedWeChat details:nil]); result([FlutterError errorWithCode:resultErrorNeedWeChat message:resultMessageNeedWeChat details:nil]);
return; return;
} }
//
if (![WXApi isWXAppInstalled]) { // if (![WXApi isWXAppInstalled]) {
result([FlutterError errorWithCode:@"wechat not installed" message:@"wechat not installed" details:nil]); // result([FlutterError errorWithCode:@"wechat not installed" message:@"wechat not installed" details:nil]);
return; // return;
} // }
if ([shareText isEqualToString:call.method]) { if ([shareText isEqualToString:call.method]) {
[self shareText:call result:result]; [self shareText:call result:result];
......
//
// FluwxAutoDeductHandler.h
// fluwx
//
// Created by realm on 2019/5/22.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface FluwxAutoDeductHandler : NSObject
-(instancetype) initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar;
-(void)handleAutoDeductWithCall:(FlutterMethodCall *)call result:(FlutterResult)result;
@end
NS_ASSUME_NONNULL_END
...@@ -179,6 +179,20 @@ FlutterMethodChannel *fluwxMethodChannel = nil; ...@@ -179,6 +179,20 @@ FlutterMethodChannel *fluwxMethodChannel = nil;
fluwxKeyPlatform: fluwxKeyIOS, fluwxKeyPlatform: fluwxKeyIOS,
}; };
[fluwxMethodChannel invokeMethod:@"onPayResponse" arguments:result]; [fluwxMethodChannel invokeMethod:@"onPayResponse" arguments:result];
} else if([resp isKindOfClass:[WXOpenBusinessWebViewResp class]]){
WXOpenBusinessWebViewResp *businessResp = (WXOpenBusinessWebViewResp *) resp;
NSDictionary *result = @{
description: [StringUtil nilToEmpty:businessResp.description],
errStr: [StringUtil nilToEmpty:resp.errStr],
errCode: @(businessResp.errCode),
type: businessResp.type == nil ? @5 : @(businessResp.type),
@"resultInfo": businessResp.result,
@"businessType":@(businessResp.businessType),
fluwxKeyPlatform: fluwxKeyIOS,
};
[fluwxMethodChannel invokeMethod:@"onAutoDeductResponse" arguments:result];
} }
} }
......
重要!
SDK1.8.4
1. 调整分享图片大小限制
2. 新增openBusinessView接口
SDK1.8.3
1. SDK增加调起微信刷卡支付接口
2. SDK增加小程序订阅消息接口
3. 修复小程序订阅消息接口没有resp的问题
SDK1.8.2
1. SDK增加开发票授权 WXInvoiceAuthInsert
2. SDK增加非税接口 WXNontaxPay
3. SDK增加医保接口 WXPayInsurance
4. 更换MTA库
SDK1.8.1
1. SDK打开小程序支持指定版本(体验,开发,正式版)
2. SDK分享小程序支持指定版本(体验,开发,正式版)
3. SDK支持输出log日志
SDK1.8.0
1. SDK支持打开小程序
2. SDK分享小程序支持shareTicket
SDK1.7.9
1. SDK订阅一次性消息
SDK1.7.8
1 SDK分享小程序支持大图
SDK1.7.7
1 增加SDK分享小程序
2 增加选择发票接口
SDK1.7.6
1. 提高稳定性
1 修复mta崩溃
2 新增接口支持开发者关闭mta数据统计上报
SDK1.7.5
1. 提高稳定性
2. 加快registerApp接口启动速度
SDK1.7.4
1. 更新支持iOS启用 ATS(App Transport Security)
2. 需要在工程中链接CFNetwork.framework
3. 在工程配置中的”Other Linker Flags”中加入”-Objc -all_load”
SDK1.7.3
1. 增强稳定性,适配iOS10
2. 修复小于32K的jpg格式缩略图设置失败的问题
SDK1.7.2
1. 修复因CTTeleponyNetworkInfo引起的崩溃问题
SDK1.7.1
1. 支持兼容ipv6(提升稳定性)
2. xCode Version 7.3.1 (7D1014) 编译
SDK1.7
1. 支持兼容ipv6
2. 修复若干问题增强稳定性
SDK1.6.3
1. xCode7.2 构建的sdk包。
2. 请使用xCode7.2进行编译。
3. 需要在Build Phases中Link Security.framework
4. 修复若干小问题。
SDK1.6.2
1、xCode7.1 构建的sdk包
2、请使用xCode7.1进行编译
SDK1.6.1
1、修复armv7s下,bitcode可能编译不过
2、解决warning
SDK1.6
1、iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
受此影响,当你的应用在iOS 9中需要使用微信SDK的相关能力(分享、收藏、支付、登录等)时,需要在“Info.plist”里增加如下代码:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
2、开发者需要在工程中链接上 CoreTelephony.framework
3、解决bitcode编译不过问题
SDK1.5
1、废弃safeSendReq:接口,使用sendReq:即可。
2、新增+(BOOL) sendAuthReq:(SendAuthReq*) req viewController : (UIViewController*) viewController delegate:(id<WXApiDelegate>) delegate;
支持未安装微信情况下Auth,具体见WXApi.h接口描述
3、微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况。开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib。
...@@ -78,6 +78,13 @@ StreamController _onQRCodeScannedController = new StreamController(); ...@@ -78,6 +78,13 @@ StreamController _onQRCodeScannedController = new StreamController();
///after uer scanned the QRCode you just received ///after uer scanned the QRCode you just received
Stream get onQRCodeScanned => _onQRCodeScannedController.stream; Stream get onQRCodeScanned => _onQRCodeScannedController.stream;
StreamController<WeChatAutoDeductResponse> _responseAutoDeductController =
new StreamController.broadcast();
/// Response from AutoDeduct
Stream<WeChatAutoDeductResponse> get responseFromAutoDeduct =>
_responseAutoDeductController.stream;
final MethodChannel _channel = const MethodChannel('com.jarvanmo/fluwx') final MethodChannel _channel = const MethodChannel('com.jarvanmo/fluwx')
..setMethodCallHandler(_handler); ..setMethodCallHandler(_handler);
...@@ -103,6 +110,9 @@ Future<dynamic> _handler(MethodCall methodCall) { ...@@ -103,6 +110,9 @@ Future<dynamic> _handler(MethodCall methodCall) {
_onAuthGotQRCodeController.add(methodCall.arguments); _onAuthGotQRCodeController.add(methodCall.arguments);
} else if ("onQRCodeScanned" == methodCall.method) { } else if ("onQRCodeScanned" == methodCall.method) {
_onQRCodeScannedController.add(null); _onQRCodeScannedController.add(null);
} else if ("onAutoDeductResponse" == methodCall.method) {
_responseAutoDeductController
.add(WeChatAutoDeductResponse.fromMap(methodCall.arguments));
} }
return Future.value(true); return Future.value(true);
...@@ -146,7 +156,7 @@ void dispose({ ...@@ -146,7 +156,7 @@ void dispose({
} }
if (paymentResponse) { if (paymentResponse) {
_responseAuthController.close(); _responsePaymentController.close();
} }
if (onAuthByQRCodeFinished) { if (onAuthByQRCodeFinished) {
...@@ -301,6 +311,40 @@ Future subscribeMsg({ ...@@ -301,6 +311,40 @@ Future subscribeMsg({
); );
} }
/// please read official docs.
Future autoDeDuct(
{@required String appId,
@required String mchId,
@required String planId,
@required String contractCode,
@required String requestSerial,
@required String contractDisplayAccount,
@required String notifyUrl,
@required String version,
@required String sign,
@required String timestamp,
String returnApp = '3',
int businessType = 12}) async {
return await _channel.invokeMethod("autoDeduct", {
'appid': appId,
'mch_id': mchId,
'plan_id': planId,
'contract_code': contractCode,
'request_serial': requestSerial,
'contract_display_account': contractDisplayAccount,
'notify_url': notifyUrl,
'version': version,
'sign': sign,
'timestamp': timestamp,
'return_app': returnApp,
"businessType": businessType
});
}
Future<bool> openWeChatApp() async {
return await _channel.invokeMethod("openWXApp");
}
_handleOnAuthByQRCodeFinished(MethodCall methodCall) { _handleOnAuthByQRCodeFinished(MethodCall methodCall) {
int errCode = methodCall.arguments["errCode"]; int errCode = methodCall.arguments["errCode"];
_authByQRCodeFinishedController.add(AuthByQRCodeResult( _authByQRCodeFinishedController.add(AuthByQRCodeResult(
......
...@@ -130,3 +130,24 @@ class WeChatSubscribeMsgResp { ...@@ -130,3 +130,24 @@ class WeChatSubscribeMsgResp {
reserved = map["reserved"], reserved = map["reserved"],
scene = map["scene"]; scene = map["scene"];
} }
class WeChatAutoDeductResponse {
final String errStr;
final int type;
final String platform;
final int errCode;
final int businessType;
final String resultInfo;
final String androidTransaction;
final String androidOpenId;
WeChatAutoDeductResponse.fromMap(Map map)
: platform = map["platform"],
errStr = map["errStr"],
androidTransaction = map["transaction"],
type = map["type"],
errCode = map["errCode"],
androidOpenId = map["openId"],
businessType = map["businessType"],
resultInfo = map["resultInfo"];
}
name: fluwx name: fluwx
description: A implement of WeChatSDK on Flutter.Fluwx makes possible using WeChatSDK in Flutter.Enjoy sharing or payment in Flutter. description: A implement of WeChatSDK on Flutter.Fluwx makes possible using WeChatSDK in Flutter.Enjoy sharing or payment in Flutter.
version: 0.6.1 version: 1.0.3
author: JarvanMo <jarvan.mo@gmail.com> author: JarvanMo <jarvan.mo@gmail.com>
homepage: https://github.com/JarvanMo/fluwx homepage: https://github.com/JarvanMo/fluwx
environment: environment:
sdk: ">=2.0.0-dev.58.0 <3.0.0" sdk: ">=2.1.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec # following page: https://www.dartlang.org/tools/pub/pubspec
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论