9

Android开发 对接微信分享SDK总结 - Stars-one

 1 year ago
source link: https://www.cnblogs.com/stars-one/p/16848763.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Android开发 对接微信分享SDK总结

本文为作者原创,允许转载,不过请在文章开头明显处注明链接和出处!!! 谢谢配合~
作者:stars-one
链接:https://www.cnblogs.com/stars-one/p/16848763.html

本篇大约有7926个字,阅读预计需要9.91分钟


原文:Android开发 对接微信分享SDK总结 - Stars-One的杂货小窝

公司项目需要对接微信分享,本来之前准备对接友盟分享的,但友盟的分享实际参数太多,而我又只需要对接一个微信分享,于是便是选择总结对接官方的

顺便把微信SDK的APPID申请的流程也一起记录了

1.注册获得APPID

前往微信公众平台,使用企业认证的开发者账号进行登录,提交应用包名和签名指纹文件,可以生成一个appId,有了此appId账号才能有侯勋的操作

通过输入命令可查看签名文件的md5等信息:

keytool -list -v -keystore qj_test.keystore
1210268-20221031163915914-1759212029.png

注意:上述输完命令后需要输入密码,密码不会显示出来,密码正确则会出现下面的相关md5等信息了

微信平台比较坑的就是,它要求输入不要带:号,且还要小写的md5数值,我们稍微处理一下:我比较懒,就写了几行代码处理了,代码如下:

//改为你的md5即可
String md5 = "73:95:50:FB:F9:A9:A6:A3:F2:74:E0:25:64:EB:E7:48";
String result = md5.replaceAll(":", "").toLowerCase();
System.out.println(result);

输出结果复制一下,就得到了符合规范的md5了

1210268-20221031170203123-841553343.png

2.添加依赖

implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'

官方文档提供的写法是不固定版本号的,我这里觉得还是固定版本号比较好,需要依赖中央仓库即可

3.初始化启动分享

// APP_ID 替换为你的应用从官方网站申请到的合法appID
private static final String APP_ID = "wx88888888";

// IWXAPI 是第三方 app 和微信通信的 openApi 接口
private IWXAPI api;

private void regToWx(Context context) {
    // 通过 WXAPIFactory 工厂,获取 IWXAPI 的实例
    api = WXAPIFactory.createWXAPI(context, APP_ID, true);

    // 将应用的 appId 注册到微信
    api.registerApp(APP_ID);

    //建议动态监听微信启动广播进行注册到微信
    context.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            // 将该 app 注册到微信
            api.registerApp(APP_ID);
        }
    }, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));

}

之后在分享的Activity或Application中进行初始化,调用regToWx(),如

regToWx(MainActivity.this)

PS: 这里可以看下下面提到的工具类封装

4.使用微信分享

经过上面的步骤,我们已经能够使用微信分享了,使用IWXAPI那个对象即可,具体可以查看文档WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档

api.sendReq(req);

不过需要注意一下Android11的适配,需要在AndroidManifest.xml声明

<queries>
    <!-- 指定微信包名-->
    <package android:name="com.tencent.mm" />
</queries>
1210268-20221101181650067-1205492507.png

这里我是封装了一个工具类,源码在下一章节,主要封装了分享文本,图片,视频和网页链接,至于分享小程序和分享音乐文件没有需求,就暂时没有对接,各位可以参考的完善即可

这里顺便补充一下,由于我自己个人没法成功申请到微信应用平台的APPID,于是我就是使用了另外项目的的APPID来进行测试

测试的发现,只要你使用同个签名文件,同时,把build.gradle里面的applicationId改成填写的包名,微信分享就是能够正常的使用

举个例子,我们有一个应用包名为com.starsone.test的应用已经申请到了APPID

这个时候,我们另外个项目,包名与其不同,但我们想要测试一下分享功能,可以进行以下的操作:

修改app模块里的build.gradle,将applicationId改为com.starsone.test包名,并使用相同的签名文件打包即可使用同个APPID测试分享功能了,如下图所示:

1210268-20221101182703706-650832898.png

5.添加回调

如果项目中需要对分享成功或失败进行监听,来进行进一步的逻辑处理,可以按照微信官方的文档添加一个WxEntryActivity实现

由于我开发的项目暂时无需,所以没怎么研究,这里稍微简单的补充一下:

我们需要创建一个WXEntryActivity作为回调的接收,WXEntryActivity没有页面,主要实现微信的回调接口IWXAPIEventHandler即可,代码如下:


public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    public void onReq(BaseReq baseReq) {

    }

    @Override
    public void onResp(BaseResp baseResp) {

    }
}
<activity
    android:name=".wxapi.WXEntryActivity"
    android:exported="true"
    android:launchMode="singleTask"
    android:taskAffinity="com.tyky.share"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

这里,注意,Activity是要处于你当前包名下的wxapi文件夹,如我自己的例子,当前包名是com.tyky.share,也是我在新建一层wxapi包名,并将Activity放在里面,如下图所示

1210268-20221101180852246-1892159363.png

这里由于我没有用到,所以就没有在方法里补充对应的逻辑了

逻辑解释如下:

通过api.sendReq(req)分享内容,发送的请求会将回调一次 onReq() 方法,之后微信分享完成(成功或取消)之后,会将响应结果将回调到 onResp() 方法

工具类封装

工具类用到了以下两个依赖,记得先导入

implementation 'org.apache.commons:commons-lang3:3.9'
// Android的工具类   https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md
implementation 'com.blankj:utilcodex:1.30.6'

PS:微信SDK依赖也不要忘记哦!

点击查看工具类源码

package com.tyky.share.utils;

import android.graphics.Bitmap;

import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.MetaDataUtils;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
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.openapi.IWXAPI;

import java.io.File;

import static com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req.WXSceneSession;
import static com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req.WXSceneTimeline;

/**
 * 参考文档 [WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Share_and_Favorites/Android.html)
 * 微信分享工具类(没有对接小程序和音乐)
 *
 * @author starsone
 */
public class WxUtils {

    //从meta里读取微信平台的appId
    public static String appId = "";

    // IWXAPI 是第三方 app 和微信通信的 openApi 接口 初始化在ShareInitializer类中
    public static IWXAPI api;

    /**
     * 分享文本
     *
     * @param text        文本内容(长度需大于 0 且不超过 10KB)
     * @param flag        0:好友 1:朋友圈
     * @param title       分享标题
     * @param description 分享描述
     */
    public static void shareText(String text, int flag, String title, String description) {
        //初始化一个 WXTextObject 对象,填写分享的文本内容
        WXTextObject textObj = new WXTextObject();
        textObj.text = text;

        //用 WXTextObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = textObj;
        msg.title = title;
        msg.description = description;
        sendMessage(msg, flag);
    }

    /**
     * 分享图片
     *
     * @param imgBase64   图片base64数据
     * @param flag        0:好友 1:朋友圈
     * @param title       分享标题
     * @param description 分享描述
     */
    public static void sharePicture(String imgBase64, int flag, String title, String description) {
        //base64数据处理
        String data = imgBase64;
        if (data.contains("base64,")) {
            data = org.apache.commons.lang3.StringUtils.substringAfter(data, "base64,");
        }
        byte[] bytes = EncodeUtils.base64Decode(data);
        Bitmap bitmap = ImageUtils.bytes2Bitmap(bytes);

        //使用file存放,突破微信分享的限制
        File file = ImageUtils.save2Album(bitmap, Bitmap.CompressFormat.PNG);
        sharePictureByImgFilePath(file.getPath(), flag, title, description);
    }

    /**
     * 分享图片
     *
     * @param imgFilePath 图片本地路径
     * @param flag        0:好友 1:朋友圈
     * @param title       分享标题
     * @param description 分享描述
     */
    public static void sharePictureByImgFilePath(String imgFilePath, int flag, String title, String description) {
        //初始化一个 WXImageObject 对象,填写分享图片
        WXImageObject wxImageObject = new WXImageObject();
        wxImageObject.imagePath = imgFilePath;

        //用 WXTextObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = wxImageObject;
        msg.title = title;
        msg.description = description;
        sendMessage(msg, flag);
    }

    /**
     * 分享视频
     *
     * @param videoUrl    视频链接
     * @param flag        0:好友 1:朋友圈
     * @param title       分享标题
     * @param description 分享描述
     */
    public static void shareVideo(String videoUrl, int flag, String title, String description) {
        //初始化一个 WXImageObject 对象,填写分享图片
        WXVideoObject wxImageObject = new WXVideoObject();
        wxImageObject.videoUrl = videoUrl;

        //用 WXTextObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = wxImageObject;
        msg.title = title;
        msg.description = description;
        sendMessage(msg, flag);
    }

    /**
     * 分享网页
     *
     * @param webUrl      网页链接
     * @param flag        0:好友 1:朋友圈
     * @param title       分享标题
     * @param description 分享描述
     */
    public static void shareWeb(String webUrl, int flag, String title, String description) {
        //初始化一个 WXImageObject 对象,填写分享图片
        WXWebpageObject wxImageObject = new WXWebpageObject();
        wxImageObject.webpageUrl = webUrl;

        //用 WXTextObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = wxImageObject;
        msg.title = title;
        msg.description = description;
        sendMessage(msg, flag);
    }


    /**
     * @param msg  分享内容实体数据
     * @param flag 0:好友 1:朋友圈
     */
    private static void sendMessage(WXMediaMessage msg, int flag) {
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());  //transaction字段用与唯一标示一个请求
        req.message = msg;

        //朋友圈:WXSceneTimeline
        //会话:WXSceneSession
        if (flag == 1) {
            req.scene = WXSceneTimeline;
        } else {
            req.scene = WXSceneSession;
        }

        //调用 api 接口,发送数据到微信
        api.sendReq(req);
    }
}

工具类使用的时候,记得在注册的时候一起进行初始化,把上述第三步的初始化方法代码改为如下面:

private void regToWx(Context context) {
    String APP_ID = WxUtils.appId;

    // 通过 WXAPIFactory 工厂,获取 IWXAPI 的实例
    WxUtils.api = WXAPIFactory.createWXAPI(context, APP_ID, true);

    // 将应用的 appId 注册到微信
    WxUtils.api.registerApp(APP_ID);

    //建议动态监听微信启动广播进行注册到微信
    context.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            // 将该 app 注册到微信
            WxUtils.api.registerApp(APP_ID);
        }
    }, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));
}

之后在Application或Activity进行初始化,其他步骤不变

1、配置签名的坑

解决:一定要MD5、小写、不要带冒号,最好用官方给的签名获取工具。

2、没有注册API

解决:API是运行重复注册的,并且也不是耗时任务,所以不妨放在Activity的onCreate下面,记得写这个。

3、分享的图标

解决:分享的图标大小不能超过32K,要是jpg格式。

3、分享图标自己能看到,好友看不到

解决:修改分享的标题和内容,不要触及微信的敏感词检测系统,多试几下。

4、没有回调

解决:一定要注意WXEntryActivity的包名路径是否正确,已经配置export=true

5、确定了问题4后还是调不起来

你确定有在WXEntryActivity的onCreate里面注册API并且调用 api.handleIntent(getIntent(), this);? 估计你没有吧?

6、回调到其他页面

解决:没办法直接回调到其他页面,但可以通过广播、EventBus等通知的实现来通知其他页面刷新,同时结束WXEntryActivity的页面。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK