github地址:https://github.com/afresh/react-native-wechat-android
网上已有成熟的第三方插件react-native-wechat(以下简称RNW),本项目是由该插件源码移植过来的,并在原插件基础上实现导入官方SDK和发送小程序消息的功能。
本项目基于android端移植开发,有兴趣的同学可自行探索ios端移植。
目录
准备工作
想要使用微信登录、支付、分享收藏消息、拉起小程序等功能,必须在微信开放平台创建移动应用,如需拉起小程序,还须关联小程序并授权APP跳转小程序,详细操作此处不做多说。
接入SDK
阅读微信Android接入指南
- 在开放平台应用详情页获取到AppID。
- 在RN项目的 /android/app/build.gradle 文件中添加依赖
dependencies {
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
-
在 /android/app/src/main/AndroidManifest.xml 文件中添加必要的权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
签名生成工具
访问Android资源下载,下载签名生成工具。
将签名生成工具安装到android调试机(已安装需要签名的APP)上,打开 -> 填写包名com.[wechat_android] -> 生成签名,再将签名和包名填写到微信开放平台。
代码移植
安卓原生移植
WeChatModule.java
添加文件 /android/app/src/main/java/com/[wechat_android]/WeChatModule.java
[wechat_android]为包名。
对RNW源码进行了修改:SDK导入的修改及新增发送小程序消息功能。
package com.[wechat_android]; //todo: 换成你的包名
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXFileObject;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXMusicObject;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.modelpay.PayResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
if (type.equals("miniProgram")) {
__jsonToMiniProgramMedia(data, new MediaObjectCallback() {
@Override
public void invoke(@Nullable WXMediaMessage.IMediaObject mediaObject, @Nullable Bitmap bitmap) {
if (mediaObject == null) {
callback.invoke(INVALID_ARGUMENT);
} else {
thumbImage = bitmap;
WeChatModule.this._share(scene, data, thumbImage, mediaObject, callback);
}
}
});
return;
}
private void __jsonToMiniProgramMedia(ReadableMap data, final MediaObjectCallback callback) {
if (!data.hasKey("imageUrl")) {
callback.invoke(null, null);
return;
}
String imageUrl = data.getString("imageUrl");
Uri imageUri;
try {
imageUri = Uri.parse(imageUrl);
// Verify scheme is set, so that relative uri (used by static resources) are not
// handled.
if (imageUri.getScheme() == null) {
imageUri = getResourceDrawableUri(getReactApplicationContext(), imageUrl);
}
} catch (Exception e) {
imageUri = null;
}
if (imageUri == null) {
callback.invoke(null, null);
return;
}
this._getImage(imageUri, null, new ImageCallback() {
@Override
public void invoke(@Nullable Bitmap bitmap) {
WXMiniProgramObject ret = new WXMiniProgramObject();
ret.webpageUrl = data.getString("webpageUrl");
ret.userName = data.getString("userName");
ret.path = data.getString("path");
callback.invoke(bitmap == null ? null : ret, bitmap);
}
});
}
WeChatPackage.java
添加文件 /android/app/src/main/java/com/[wechat_android]/WeChatPackage.java
无需修改,直接复制RNW的。
添加WeChatPackage包
在文件 /android/app/src/main/java/com/wechat_android/MainApplication.java 中添加WeChatPackage包。
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new WeChatPackage() //todo: 添加包
);
}
React Native 代码移植
安装events插件
npm install events --save
wechat.js
添加文件 ./wechat.js
无需修改,直接复制RNW的。
使用说明
原RNW的API
API Documentation
微信登录和发送小程序示例
App.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
import * as WeChat from './wechat';
let resolveAssetSource = require('resolveAssetSource');
export default class App extends Component {
componentDidMount() {
WeChat.registerApp('appid'); //应用唯一标识,在微信开放平台提交应用审核通过后获得
};
_sendAuthRequest = () => {
let scope = 'snsapi_userinfo'; //应用授权作用域,如获取用户个人信息则填写snsapi_userinfo
let state = 'wechat_sdk_demo'; //用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
//判断微信是否安装
WeChat.isWXAppInstalled()
.then((isInstalled) => {
if (isInstalled) {
//发送授权请求
WeChat.sendAuthRequest(scope, state)
.then(responseCode => {
//todo: 返回code码,通过code获取access_token
// this.getAccessToken(responseCode.code);
// 暂无this.getAccessToken方法,此方法为调用 通过code获取access_token 的微信接口
// 详情请见https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&token=cff29f44fb9601cce318ec1c733dfd17c0a8de3b&lang=zh_CN
})
.catch(err => {
console.log('登录授权发生错误:', err.message);
})
} else {
console.log('没有安装微信,请先安装微信客户端在进行登录');
}
})
};
_shareToSession = () => {
//判断微信是否安装
WeChat.isWXAppInstalled()
.then((isInstalled) => {
if (isInstalled) {
//发送授权请求
let imageResource = require('./icon64_wx_logo.png'); //小程序消息封面图片,小于128k
WeChat.shareToSession({
type: 'miniProgram',
webpageUrl: "https://open.weixin.qq.com/", //兼容低版本的网页链接
userName: "gh_xxx", //小程序原始id
path: "/pages/media", //小程序页面路径
title: '微信小程序消息', //小程序消息title
description: '发送微信小程序消息给好友', //小程序消息desc
mediaTagName: '小程序消息',
messageAction: undefined,
messageExt: undefined,
imageUrl: resolveAssetSource(imageResource).uri //小程序消息封面图片,小于128k
})
.then(result => {
console.log('成功发送微信小程序消息给好友', result);
})
.catch(err => {
console.log('发送微信小程序消息发生错误:', err.message);
})
} else {
console.log('没有安装微信,请先安装微信客户端在进行登录');
}
})
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to WeChat for Android!
</Text>
{/* 微信登录demo */}
<TouchableOpacity onPress={() => {this._sendAuthRequest()}}>
<Text style={styles.instructions}>
To Login
</Text>
</TouchableOpacity>
{/* 发送小程序消息到好友 */}
<TouchableOpacity onPress={() => {this._shareToSession()}}>
<Text style={styles.instructions}>
To Share Mini
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});