【React-Native】集成微信官方安卓端SDK,实现微信登录、发送/分享小程序消息等功能

github地址:https://github.com/afresh/react-native-wechat-android

网上已有成熟的第三方插件react-native-wechat(以下简称RNW),本项目是由该插件源码移植过来的,并在原插件基础上实现导入官方SDK和发送小程序消息的功能。

本项目基于android端移植开发,有兴趣的同学可自行探索ios端移植。

目录

准备工作

接入SDK 

阅读微信Android接入指南

签名生成工具

代码移植

安卓原生移植

WeChatModule.java

WeChatPackage.java

添加WeChatPackage包

React Native 代码移植

安装events插件

wechat.js

使用说明

原RNW的API

API Documentation

微信登录和发送小程序示例

App.js


准备工作

想要使用微信登录、支付、分享收藏消息、拉起小程序等功能,必须在微信开放平台创建移动应用,如需拉起小程序,还须关联小程序并授权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,
  },
});

猜你喜欢

转载自blog.csdn.net/danding_ge/article/details/81122002