提交 2781be93 authored 作者: nelson1110's avatar nelson1110

Merge branch 'master' of https://github.com/JarvanMo/fluwx

...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
适用于Flutter的微信SDK,方便快捷。 适用于Flutter的微信SDK,方便快捷。
## 写在前面 ## 使用需知
使用```Fluwx```之前,强烈建议先阅读[微信SDK官方文档](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1) 使用```Fluwx```之前,强烈建议先阅读[微信SDK官方文档](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1)
这有助于你使用```Fluwx``````Fluwx```的api字段名称基本和官方的字段名称是一致的。 这有助于你使用```Fluwx```
ios部分还在持续开发中。
### 目前功能 ### 目前功能
* 文本分享。 * 文本分享。
* 网站分享。 * 网站分享。
...@@ -16,24 +16,40 @@ ...@@ -16,24 +16,40 @@
* 小程序分享。 * 小程序分享。
* 发送Auth认证。 * 发送Auth认证。
## 技术参数
Android部分使用到了```kotlin-1.2.60```。以下是Android部分所涉及到的技术:
```gradle
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.1.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.24.0'
implementation 'top.zibin:Luban:1.1.8'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
```
iOS部分涉及到的技术:
```podspec
s.dependency 'WechatOpenSDK','~> 1.8.2'
```
## 引入 ## 引入
在```pubspec.yaml```文件中添加如下代码: 在```pubspec.yaml```文件中添加如下代码:
```yaml ```yaml
dependencies: dependencies:
fluwx: ^0.0.3 fluwx: ^0.0.3
``` ```
## 初始化 ## 初始化
使用```Fluwx```前,需要进行初始化操作:
```dart ```dart
Fluwx.registerApp(RegisterModel(appId: "your app id", doOnAndroid: true, doOnIOS: true)); Fluwx.registerApp(RegisterModel(appId: "your app id", doOnAndroid: true, doOnIOS: true));
``` ```
- ```appId```:在微信平台申请的appId。 - ```appId```:在微信平台申请的appId。
- ```doOnAndroid```:是否在android平台上执行此操作。 - ```doOnAndroid```:是否在android平台上执行此操作。
- ```doOnIOS```:是否在平台上执行此操作。</br> - ```doOnIOS```:是否在平台上执行此操作。</br>
每一个字段都是非必须的,但是如果不传appId或```doOnAndroid: false```或者```doOnIOS: false```,在使用前请务必手动注册```WXApi```,以保证 每一个字段都是非必须的,但是如果不传```appId```或```doOnAndroid: false```或者```doOnIOS: false```,在使用前请务必手动注册```WXApi```,以保证
Fluwx正常工作。 ```Fluwx```正常工作。
注册完成后,请在对应平台添加如下代码: 注册完成后,请在使用```Fluwx```前在对应平台添加如下代码:
Android上: Android上:
```Kotlin ```kotlin
FluwxShareHandler.setWXApi(wxapi) FluwxShareHandler.setWXApi(wxapi)
``` ```
iOS上: iOS上:
...@@ -41,40 +57,33 @@ dependencies: ...@@ -41,40 +57,33 @@ dependencies:
isWeChatRegistered = YES; isWeChatRegistered = YES;
``` ```
> 注意:尽管可以通过Fluwx完成微信注册,但一些操作依然需要在对应平台进行设置,如配置iOS的URLSchema,Android上的WXEntryActivity等。
### 传送门
* [分享功能](docs/SHARE.md)
* [Auth认证](docs/SEND_AUTH.md)
* [支付](docs/WXPay.md)
* [回调](docs/RESPONSE.md)
注意:尽管可以通过Fluwx完成微信注册,但一些操作依然需要在对应平台进行设置,如配置iOSURLSchema等。
## 开始分享
以分享文本和网址为例:
```dart
var fluwx = Fluwx();
fluwx.share(WeChatShareImageModel(image: "imagePath",thumbnail: "thumbanailPath"));
fluwx.share(
WeChatShareWebPageModel(
webPage: "https://github.com/JarvanMo/fluwx",
title: "Fluwx",
thumbnail: "http://d.hiphotos.baidu.com/image/h%3D300/sign=1057e22c6ed9f2d33f1122ef99ee8a53/3bf33a87e950352aadfff8c55f43fbf2b3118b65.jpg",
)).then((result){
},
onError: (msg){
});
```
```fluwx.share(shareModel)```返回值为:
```dart
{
"platform":"Android",//或者iOS
result:true //或者false,取决于WXApi.sendRequest()的结果
}
```
```fluwx.share(WeChatShareModel)```目前仅支持系统内```WeChatShareModel```的子类,不支持自定义。
所有字段名字和官方文档基本是一致的。
## 图片处理
图片仅支持```png```和```jpg```。
目前所有需要图片的地方支持网络图片及assets图片。</br>
使用assets图片需要添加```assets://```。</br>
也可以在assets图片添加```?package=package_name```以读取指定包的图片。</br>
未来可能支持```file://```</br>
如果不指定schema或者schema错误,将会被处理为网络图片,请谨慎。</br>
## 注意
所有涉及缩略的最好给Fluwx一个合格的图片(小于32k,小程序小于120k),否则Fluwx将会对图片进行处理,这样做的结果可能并不是你所预期的,如缩略图被缩放。
### 更多功能敬请请期待 ### 更多功能敬请请期待
## LICENSE
Copyright 2018 OpenFlutter Project
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jarvan.fluwx"></manifest> package="com.jarvan.fluwx">
<application>
<activity
android:name=".wxapi.FluwxWXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="sensorPortrait"
android:theme="@style/DisablePreviewTheme" />
</application>
</manifest>
package com.jarvan.fluwx.wxapi
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import com.jarvan.fluwx.handler.FluwxResponseHandler
import com.jarvan.fluwx.handler.WXAPiHandler
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
class FluwxWXEntryActivity:Activity(), IWXAPIEventHandler {
// IWXAPI 是第三方app和微信通信的openapi接口
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WXAPiHandler.wxApi?.handleIntent(intent, this)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
WXAPiHandler.wxApi?.handleIntent(intent, this)
}
override fun onReq(baseReq: BaseReq) {
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
override fun onResp(resp: BaseResp) {
FluwxResponseHandler.handleResponse(resp)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DisablePreviewTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowDisablePreview">true</item>
</style>
</resources>
\ No newline at end of file
### 微信调回
微信的回调也要根据平台的不同进行差异化处理。
### Android
除了支付以外的回调,你需要在你的```WXEntryActivity```中添加如下代码:
```kotlin
override fun onResp(resp: BaseResp) {
FluwxResponseHandler.handleResponse(resp)
}
```
你也可以直接继承```FluwxWXEntryActivity```
\ No newline at end of file
## 发送Auth验证
```Fluwx```目前只支持获取```code```,若要获取```access_token```请在服务器端完成。
```dart
fluwx.sendAuth(WeChatSendAuthModel(
scope: "snsapi_userinfo",
state:"wechat_sdk_demo_test",
));
```
### 简述
目前```Fluwx```并不是支持所有的分享类型,目前仅支持文本分享、图片分享、网址分享
音乐、视频以及小程序的分享。未来会考虑增加更多支持。
> 注意:目前分享中涉及到图片的地方仅支持```png```和```jpg```,支持网络图片及```assets```图片。<br>
> 使用```assets```图片需要添加```assets://```。<br>
> 也可以在```assets```图片添加```?package=package_name```以读取指定包的图片。<br>
> 未来可能支持```file://```,目前以```file://```图片不会做任何处理。<br>
> 如果不指定schema或者schema错误,将会被处理为网络图片,请谨慎。<br>
> 由于微信的限制,一般的缩略图要小于32k(小程序的缩略图要小于120k),所以在使用缩略的时候<br>
> 很有必要使用一张合格的缩略图,否则```Fluwx```进行压缩,其结果可能并不是你所预期的。
### 分享去处
绝大部分分享可以分享到会话,朋友圈,收藏(小程序目前只能分享到会话)。默认分享到会话。
```dart
///[WeChatScene.SESSION]会话
///[WeChatScene.TIMELINE]朋友圈
///[WeChatScene.FAVORITE]收藏
enum WeChatScene {
SESSION,
TIMELINE,
FAVORITE
}
```
### 返回值处理
```fluwx.share(model)```返回的是一个```Map```:
```dart
{
"platform":"Android",//或者iOS
result:true //或者false,取决于WXApi.sendRequest()的结果
}
```
### 分享文本
```dart
fluwx.share(WeChatShareTextModel(
text: "text from fluwx",
transaction: "transaction}",//仅在android上有效,下同。
scene: scene
));
```
### 分享图片
```dart
fluwx.share(WeChatShareImageModel(
image: _imagePath,
thumbnail: _thumbnail,
transaction: _imagePath,
scene: scene,
description: "image"));
```
> 注意:如果`不指定 ```thumbnail```,那么```Fluwx```将尝试从```image```中获取缩略图。
### 分享音乐
```dart
var model = WeChatShareMusicModel(
title: _title,
description: _description,
transaction: "music",
musicUrl: _musicUrl,
musicLowBandUrl: _musicLowBandUrl
);
fluwx.share(model);
```
音乐的分享有两种:```musicUrl``````musicLowBandUrl```。这两种形式是不共存的,如果
都二者都进行了赋值,那么只会读取```musicUrl```
### 分享视频
```dart
var model = new WeChatShareVideoModel(
videoUrl: _videoUrl,
transaction: "video",
videoLowBandUrl: _videoLowBandUrl,
thumbnail: _thumnail,
description: _description,
title: _title
);
fluwx.share(model);
```
视频的分享有两种:```videoUrl``````videoLowBandUrl```。这两种形式是不共存的,如果
都二者都进行了赋值,那么只会读取```videoUrl```
\ No newline at end of file
...@@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; ...@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
import 'package:fluwx_example/share_video_page.dart';
import 'share_music.dart'; import 'share_music.dart';
import 'share_web_page.dart'; import 'share_web_page.dart';
import 'share_image_page.dart'; import 'share_image_page.dart';
...@@ -32,6 +33,7 @@ class _MyAppState extends State<MyApp> { ...@@ -32,6 +33,7 @@ class _MyAppState extends State<MyApp> {
"shareImage":(context) => ShareImagePage(), "shareImage":(context) => ShareImagePage(),
"shareWebPage":(context) => ShareWebPagePage(), "shareWebPage":(context) => ShareWebPagePage(),
"shareMusic":(context) => ShareMusicPage(), "shareMusic":(context) => ShareMusicPage(),
"shareVideo":(context) => ShareVideoPage(),
}, },
home: new Scaffold( home: new Scaffold(
appBar: new AppBar( appBar: new AppBar(
...@@ -45,23 +47,29 @@ class _MyAppState extends State<MyApp> { ...@@ -45,23 +47,29 @@ class _MyAppState extends State<MyApp> {
class ShareSelectorPage extends StatelessWidget { class ShareSelectorPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Column( return Center(
children: <Widget>[ child: new Column(
new OutlineButton(onPressed: () { children: <Widget>[
Navigator.of(context).pushNamed("shareText"); new OutlineButton(onPressed: () {
}, child: const Text("share text")), Navigator.of(context).pushNamed("shareText");
new OutlineButton(onPressed: () { }, child: const Text("share text")),
Navigator.of(context).pushNamed("shareImage"); new OutlineButton(onPressed: () {
}, child: const Text("share image")), Navigator.of(context).pushNamed("shareImage");
new OutlineButton(onPressed: () { }, child: const Text("share image")),
Navigator.of(context).pushNamed("shareWebPage"); new OutlineButton(onPressed: () {
Navigator.of(context).pushNamed("shareWebPage");
}, child: const Text("share webpage")), }, child: const Text("share webpage")),
new OutlineButton(onPressed: () { new OutlineButton(onPressed: () {
Navigator.of(context).pushNamed("shareMusic"); Navigator.of(context).pushNamed("shareMusic");
}, child: const Text("share music")), }, child: const Text("share music")),
], new OutlineButton(onPressed: () {
Navigator.of(context).pushNamed("shareVideo");
}, child: const Text("share video")),
],
),
); );
} }
} }
...@@ -26,7 +26,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -26,7 +26,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Scaffold( return new Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("ShareWebPage"), title: const Text("ShareMusicPage"),
actions: <Widget>[ actions: <Widget>[
IconButton(icon: Icon(Icons.share,color: Colors.white,), onPressed: _share) IconButton(icon: Icon(Icons.share,color: Colors.white,), onPressed: _share)
], ],
...@@ -128,7 +128,8 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -128,7 +128,8 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
description: _description, description: _description,
transaction: "music", transaction: "music",
musicUrl: _musicUrl, musicUrl: _musicUrl,
musicLowBandDataUrl: _musicLowBandUrl musicLowBandUrl: _musicLowBandUrl,
thumbnail: _thumnail
); );
fluwx.share(model); fluwx.share(model);
......
import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart';
class ShareVideoPage extends StatefulWidget {
@override
_ShareMusicPageState createState() => _ShareMusicPageState();
}
class _ShareMusicPageState extends State<ShareVideoPage> {
Fluwx fluwx;
String _videoUrl = "http://www.qq.com";
String _videoLowBandUrl = "http://www.qq.com";
String _title = "Beyond";
String _description = "A Popular Rock Band From China";
String _thumnail ="assets://images/logo.png";
WeChatScene scene = WeChatScene.SESSION;
@override
void initState() {
super.initState();
fluwx = new Fluwx();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: const Text("ShareVideoPage"),
actions: <Widget>[
IconButton(icon: Icon(Icons.share,color: Colors.white,), onPressed: _share)
],
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: new Column(
children: <Widget>[
new TextField(
controller: TextEditingController(text: "http://staff2.ustc.edu.cn/~wdw/softdown/index.asp/0042515_05.ANDY.mp3"),
onChanged: (str){
_videoUrl = str;
},
decoration: InputDecoration(
labelText: "video url"
),
),
new TextField(
controller: TextEditingController(text: "http://www.qq.com"),
onChanged: (str){
_videoLowBandUrl = str;
},
decoration: InputDecoration(
labelText: "video low band url"
),
),
new TextField(
controller: TextEditingController(text: "Beyond"),
onChanged: (str){
_title = str;
},
decoration: InputDecoration(
labelText: "title"
),
),
new TextField(
controller: TextEditingController(text: "A Popular Rock Band From China"),
onChanged: (str){
_description = str;
},
decoration: InputDecoration(
labelText: "description"
),
),
new TextField(
controller: TextEditingController(text: "assets://images/logo.png"),
onChanged: (str){
_thumnail = str;
},
decoration: InputDecoration(
labelText: "thumbnail"
),
),
new Row(
children: <Widget>[
const Text("分享至"),
Row(
children: <Widget>[
new Radio<WeChatScene>(
value: WeChatScene.SESSION,
groupValue: scene,
onChanged: handleRadioValueChanged
),
const Text("会话")
],
),
Row(
children: <Widget>[
new Radio<WeChatScene>(
value: WeChatScene.TIMELINE,
groupValue: scene,
onChanged: handleRadioValueChanged
),
const Text("朋友圈")
],
),
Row(
children: <Widget>[
new Radio<WeChatScene>(
value: WeChatScene.FAVORITE,
groupValue: scene,
onChanged: handleRadioValueChanged
),
const Text("收藏")
],
)
],
)
],
),
),
);
}
void _share() {
var model = new WeChatShareVideoModel(
videoUrl: _videoUrl,
transaction: "video",
videoLowBandUrl: _videoLowBandUrl,
thumbnail: _thumnail,
description: _description,
title: _title
);
fluwx.share(model);
}
void handleRadioValueChanged(WeChatScene scene){
setState(() {
this.scene = scene;
});
}
}
...@@ -6,3 +6,4 @@ export 'src/models/wechat_share_models.dart'; ...@@ -6,3 +6,4 @@ export 'src/models/wechat_share_models.dart';
export 'src/wechat_reponse.dart'; export 'src/wechat_reponse.dart';
export 'src/wechat_scene.dart'; export 'src/wechat_scene.dart';
export 'src/models/wechat_pay_model.dart'; export 'src/models/wechat_pay_model.dart';
export 'src/models/wechat_send_auth_model.dart';
import 'package:flutter/foundation.dart';
class WeChatSendAuthModel { class WeChatSendAuthModel {
final String scope; final String scope;
final String state; final String state;
final String openId; final String openId;
WeChatSendAuthModel(this.scope, this.state,this.openId) : WeChatSendAuthModel({
@required this.scope,
this.state,
this.openId }) :
assert(scope != null && scope assert(scope != null && scope
.trim() .trim()
.isNotEmpty); .isNotEmpty);
......
enum WeChatScene { SESSION, TIMELINE, FAVORITE } ///[WeChatScene.SESSION]会话
///[WeChatScene.TIMELINE]朋友圈
///[WeChatScene.FAVORITE]收藏
enum WeChatScene {
SESSION,
TIMELINE,
FAVORITE }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论