提交 50c750a8 authored 作者: JarvanMo's avatar JarvanMo

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

......@@ -17,9 +17,9 @@ dependencies:
```dart
Fluwx.registerApp(RegisterModel(appId: "your app id", doOnAndroid: true, doOnIOS: true));
```
- appId:在微信平台申请的appId
- doOnAndroid:是否在android平台上执行此操作。
- doOnIOS:是否在平台上执行此操作。</br>
- ```appId```:在微信平台申请的appId
- ```doOnAndroid```:是否在android平台上执行此操作。
- ```doOnIOS```:是否在平台上执行此操作。</br>
每一个字段都是非必须的,但是如果不传appId或```doOnAndroid: false```或者```doOnIOS: false```,在使用前请务必手动注册```WXApi```,以保证
Fluwx正常工作。
注册完成后,请在对应平台添加如下代码:
......
package com.jarvan.fluwx
import com.jarvan.fluwx.constant.WeChatPluginMethods
import com.jarvan.fluwx.handler.FluwxLoginHandler
import com.jarvan.fluwx.handler.FluwxShareHandler
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
......@@ -32,6 +33,10 @@ class FluwxPlugin(private var registrar: Registrar) : MethodCallHandler {
return
}
if ("sendAuth" == call.method){
FluwxLoginHandler.sendAuth(call,result)
return
}
if( call.method.startsWith("share")){
FluwxShareHandler.handle(call, result)
......
package com.jarvan.fluwx.handler
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelmsg.SendAuth
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
object FluwxLoginHandler {
private var channel: MethodChannel? = null
fun setMethodChannel(channel: MethodChannel) {
FluwxLoginHandler.channel = channel
}
fun sendAuth(call: MethodCall, result: MethodChannel.Result) {
val req = SendAuth.Req()
req.scope = call.argument("scope")
req.state = call.argument("state")
result.success(WXAPiHandler.wxApi!!.sendReq(req))
}
fun handleResponse(response:BaseResp){
}
}
\ No newline at end of file
package com.jarvan.fluwx.handler
import com.jarvan.fluwx.constant.WechatPluginKeys
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
object WXAPiHandler {
private var registrar: PluginRegistry.Registrar? = null
var wxApi: IWXAPI? = null
fun setRegistrar(registrar: PluginRegistry.Registrar) {
WXAPiHandler.registrar = registrar
}
fun registerApp(call: MethodCall, result: MethodChannel.Result) {
if(!call.argument<Boolean>(WechatPluginKeys.ANDROID)){
return
}
if (wxApi != null) {
result.success(mapOf(
WechatPluginKeys.PLATFORM to WechatPluginKeys.ANDROID,
WechatPluginKeys.RESULT to true
))
return
}
val appId:String? = call.argument(WechatPluginKeys.APP_ID)
if (appId.isNullOrBlank()) {
result.error("invalid app id", "are you sure your app id is correct ?", appId)
return
}
val api = WXAPIFactory.createWXAPI(registrar!!.context().applicationContext, appId)
val registered = api.registerApp(appId)
wxApi = api
result.success(mapOf(
WechatPluginKeys.PLATFORM to WechatPluginKeys.ANDROID,
WechatPluginKeys.RESULT to registered
))
}
}
\ No newline at end of file
......@@ -155,4 +155,32 @@ public class ThumbnailCompressUtil {
return thumb;
}
public static Bitmap createScaledBitmapWithRatio(Bitmap bitmap , int maxLength, boolean recycle){
Bitmap result = bitmap;
while (true){
double ratio =((double) maxLength )/ result.getByteCount();
double width = result.getWidth() * Math.sqrt(ratio);
double height = result.getHeight() * Math.sqrt(ratio);
Bitmap tmp = Bitmap.createScaledBitmap(result, (int) width, (int)height, true);
if (result != bitmap){
result.recycle();
}
result = tmp;
if (result.getByteCount() < maxLength ) {
break;
}
}
if (recycle) {
bitmap.recycle();
}
return result;
}
}
......@@ -30,9 +30,8 @@ import okio.Source;
import top.zibin.luban.Luban;
public class WeChatThumbnailUtil {
public static final int SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH = 120;
public static final int MINI_PROGRAM_SCALED_WIDTH = 480;
public static final int SHARE_IMAGE_THUMB_LENGTH = 32;
public static final int SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH = 120 * 1024;
public static final int SHARE_IMAGE_THUMB_LENGTH = 32 * 1024;
private static final int COMMON_THUMB_WIDTH = 150;
private WeChatThumbnailUtil() {
......@@ -47,7 +46,7 @@ public class WeChatThumbnailUtil {
} else {
file = downloadImage(thumbnail);
}
return compress(file, registrar,SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH,MINI_PROGRAM_SCALED_WIDTH);
return compress(file, registrar,SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH);
}
......@@ -60,7 +59,7 @@ public class WeChatThumbnailUtil {
} else {
file = downloadImage(thumbnail);
}
return compress(file, registrar,SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH,MINI_PROGRAM_SCALED_WIDTH);
return compress(file, registrar,SHARE_MINI_PROGRAM_IMAGE_THUMB_LENGTH);
}
public static byte[] thumbnailForCommon(String thumbnail, PluginRegistry.Registrar registrar) {
......@@ -72,10 +71,10 @@ public class WeChatThumbnailUtil {
} else {
file = downloadImage(thumbnail);
}
return compress(file, registrar,SHARE_IMAGE_THUMB_LENGTH,COMMON_THUMB_WIDTH);
return compress(file, registrar,SHARE_IMAGE_THUMB_LENGTH);
}
private static byte[] compress(File file, PluginRegistry.Registrar registrar,int resultMaxLength,int scaledWidth) {
private static byte[] compress(File file, PluginRegistry.Registrar registrar,int resultMaxLength) {
if (file == null) {
return new byte[]{};
}
......@@ -87,7 +86,7 @@ public class WeChatThumbnailUtil {
.ignoreBy(resultMaxLength)
.setTargetDir(registrar.context().getCacheDir().getAbsolutePath())
.get(file.getAbsolutePath());
if (compressedFile.length() < resultMaxLength * 1024) {
if (compressedFile.length() < resultMaxLength ) {
Source source = Okio.source(compressedFile);
BufferedSource bufferedSource = Okio.buffer(source);
byte[] bytes = bufferedSource.readByteArray();
......@@ -95,12 +94,10 @@ public class WeChatThumbnailUtil {
bufferedSource.close();
return bytes;
}
byte[] result = createScaledBitmapWithRatio(compressedFile,scaledWidth);
if (result.length < resultMaxLength * 1024) {
return result;
}
return createScaledBitmapWithRatio(compressedFile,resultMaxLength);
return createScaledBitmap(compressedFile, resultMaxLength,scaledWidth);
} catch (IOException e) {
e.printStackTrace();
......@@ -108,10 +105,10 @@ public class WeChatThumbnailUtil {
return new byte[]{};
}
private static byte[] createScaledBitmapWithRatio(File file,int scaledWidth) {
private static byte[] createScaledBitmapWithRatio(File file,int resultMaxLength) {
Bitmap originBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Bitmap result = ThumbnailCompressUtil.createScaledBitmapWithRatio(originBitmap, scaledWidth, true);
Bitmap result = ThumbnailCompressUtil.createScaledBitmap(originBitmap, resultMaxLength, true);
String path = file.getAbsolutePath();
String suffix = path.substring(path.lastIndexOf("."), path.length());
......
......@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'dart:async';
import 'package:fluwx/fluwx.dart';
import 'package:fluwx_example/share_music.dart';
import 'package:fluwx_example/share_web_page.dart';
import 'share_image_page.dart';
import 'share_text_image.dart';
......@@ -30,6 +31,7 @@ class _MyAppState extends State<MyApp> {
"shareText": (context) => ShareTextPage(),
"shareImage":(context) => ShareImagePage(),
"shareWebPage":(context) => ShareWebPagePage(),
"shareMusic":(context) => ShareMusicPage(),
},
home: new Scaffold(
appBar: new AppBar(
......@@ -40,31 +42,6 @@ class _MyAppState extends State<MyApp> {
}
}
// var fluwx = Fluwx();
//// fluwx.share(WeChatShareMiniProgramModel(
//// webPageUrl: "http://www.qq.com",
//// miniProgramType:
//// WeChatShareMiniProgramModel.MINI_PROGRAM_TYPE_RELEASE,
//// userName: "gh_d43f693ca31f",
//// path: '/pages/media',
//// title: "title",
//// description: "des",
//// thumbnail:
//// 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534532387799&di=12701cc3f20c1a78a5c7524ec33b4c59&imgtype=0&src=http%3A%2F%2Fwww.cssxt.com%2Fuploadfile%2F2017%2F1208%2F20171208110834538.jpg',
//// ));
//// thumbnail: 'http://b.hiphotos.baidu.com/image/h%3D300/sign=4bfc640817d5ad6eb5f962eab1c939a3/8718367adab44aedb794e128bf1c8701a08bfb20.jpg',
// fluwx.share(
// WeChatShareWebPageModel(
// webPage: "https://github.com/JarvanMo/fluwx",
// title: "MyGithub",
// thumbnail: "assets://images/logo.png"
// )
// ).then((result){
// print("--$result");
// },onError: (msg){
// print(msg);
// });
//// fluwx.share(WeChatShareImageModel(image: "imagePath",thumbnail: "thumbanailPath"));
class ShareSelectorPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
......@@ -80,6 +57,10 @@ class ShareSelectorPage extends StatelessWidget {
Navigator.of(context).pushNamed("shareWebPage");
}, child: const Text("share webpage")),
new OutlineButton(onPressed: () {
Navigator.of(context).pushNamed("shareMusic");
}, child: const Text("share music")),
],
);
}
......
......@@ -97,6 +97,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
image: _imagePath,
thumbnail: _thumbnail,
transaction: _imagePath,
scene: scene,
description: "这是一张图"));
}
......
import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart';
class ShareMusicPage extends StatefulWidget {
@override
_ShareMusicPageState createState() => _ShareMusicPageState();
}
class _ShareMusicPageState extends State<ShareMusicPage> {
Fluwx fluwx;
String _musicUrl = "http://staff2.ustc.edu.cn/~wdw/softdown/index.asp/0042515_05.ANDY.mp3";
String _musicLowBandUrl = "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("ShareWebPage"),
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){
_musicUrl = str;
},
decoration: InputDecoration(
labelText: "music url"
),
),
new TextField(
controller: TextEditingController(text: "http://www.qq.com"),
onChanged: (str){
_musicLowBandUrl = str;
},
decoration: InputDecoration(
labelText: "music 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 = WeChatShareMusicModel(
title: _title,
description: _description,
transaction: "music",
musicUrl: _musicUrl,
musicLowBandDataUrl: _musicLowBandUrl
);
fluwx.share(model);
}
void handleRadioValueChanged(WeChatScene scene){
setState(() {
this.scene = scene;
});
}
}
......@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
import 'models/flutter_register_model.dart';
import 'models/wechat_share_models.dart';
import 'models/wechat_send_auth_model.dart';
class Fluwx {
static const Map<Type, String> _shareModelMethodMapper = {
WeChatShareTextModel: "shareText",
......@@ -27,9 +27,9 @@ class Fluwx {
return await _channel.invokeMethod("registerApp", model.toMap());
}
static Future unregisterApp(RegisterModel model) async {
return await _channel.invokeMethod("unregisterApp", model.toMap());
}
// static Future unregisterApp(RegisterModel model) async {
// return await _channel.invokeMethod("unregisterApp", model.toMap());
// }
void listen() {
_channel.setMethodCallHandler(_handler);
......@@ -58,6 +58,10 @@ class Fluwx {
}
}
Future sendAuth(WeChatSendAuthModel model) async{
return await _channel.invokeMethod("sendAuth", model.toMap());
}
Future<dynamic> _handler(MethodCall methodCall) {
if ("onShareResponse" == methodCall.method) {
_responseFromShareController.add(methodCall.arguments);
......
class WeChatSendAuthModel {
final String scope;
final String state;
WeChatSendAuthModel(this.scope, this.state) :
assert(scope != null && scope
.trim()
.isNotEmpty);
Map toMap() {
return {
"scope":scope,
"state":state
};
}
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论