发布于2022年11月4日3年前 原文:Android开发 对接微信分享SDK总结 - Stars-One的杂货小窝 公司项目需要对接微信分享,本来之前准备对接友盟分享的,但友盟的分享实际参数太多,而我又只需要对接一个微信分享,于是便是选择总结对接官方的 顺便把微信SDK的APPID申请的流程也一起记录了 步骤 1.注册获得APPID 前往微信公众平台,使用企业认证的开发者账号进行登录,提交应用包名和签名指纹文件,可以生成一个appId,有了此appId账号才能有侯勋的操作 通过输入命令可查看签名文件的md5等信息: keytool -list -v -keystore qj_test.keystore 注意:上述输完命令后需要输入密码,密码不会显示出来,密码正确则会出现下面的相关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了 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> 这里我是封装了一个工具类,源码在下一章节,主要封装了分享文本,图片,视频和网页链接,至于分享小程序和分享音乐文件没有需求,就暂时没有对接,各位可以参考的完善即可 这里顺便补充一下,由于我自己个人没法成功申请到微信应用平台的APPID,于是我就是使用了另外项目的的APPID来进行测试 测试的发现,只要你使用同个签名文件,同时,把build.gradle里面的applicationId改成填写的包名,微信分享就是能够正常的使用 举个例子,我们有一个应用包名为com.starsone.test的应用已经申请到了APPID 这个时候,我们另外个项目,包名与其不同,但我们想要测试一下分享功能,可以进行以下的操作: 修改app模块里的build.gradle,将applicationId改为com.starsone.test包名,并使用相同的签名文件打包即可使用同个APPID测试分享功能了,如下图所示: 这里如果使用分享视频或分享网页链接,在微信中会以消息卡片的形式展示,如下图所示: 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放在里面,如下图所示 这里由于我没有用到,所以就没有在方法里补充对应的逻辑了 逻辑解释如下: 通过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 org.apache.commons.lang3.StringUtils; 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 stars-one */ public class WxUtils { //从meta里读取微信平台的appId public static String appId = MetaDataUtils.getMetaDataInApp("wechat_app_id"); // IWXAPI 是第三方 app 和微信通信的 openApi 接口 初始化在ShareInitializer类中 public static IWXAPI api; /** * 分享文本 * * @param text 文本内容(长度需大于 0 且不超过 10KB) * @param flag 0:好友 1:朋友圈 * @param title 分享标题(限制长度不超过 512Bytes) * @param description 分享描述(限制长度不超过 1KB) */ 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 分享标题(限制长度不超过 512Bytes) * @param description 分享描述(限制长度不超过 1KB) */ 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 分享标题(限制长度不超过 512Bytes) * @param description 分享描述(限制长度不超过 1KB) */ 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 视频链接(文本长度不能超过10KB) * @param flag 0:好友 1:朋友圈 * @param title 分享标题(限制长度不超过 512Bytes) * @param description 分享描述(限制长度不超过 1KB) * @param thumbData 缩略图base64(不能超过32KB) */ public static void shareVideo(String videoUrl, int flag, String title, String description, String thumbData) { //初始化一个 WXImageObject 对象,填写分享图片 WXVideoObject wxImageObject = new WXVideoObject(); wxImageObject.videoUrl = videoUrl; //用 WXTextObject 对象初始化一个 WXMediaMessage 对象 WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = wxImageObject; msg.title = title; msg.description = description; if (StringUtils.isNotBlank(thumbData)) { String data = thumbData; if (data.contains("base64,")) { data = org.apache.commons.lang3.StringUtils.substringAfter(data, "base64,"); } byte[] bytes = EncodeUtils.base64Decode(data); Bitmap bitmap = ImageUtils.bytes2Bitmap(bytes); msg.setThumbImage(bitmap); } sendMessage(msg, flag); } /** * 分享网页(分享给好友会以消息卡片展示) * * @param webUrl 网页链接(文本长度不能超过10KB) * @param flag 0:好友 1:朋友圈 * @param title 分享标题(限制长度不超过 512Bytes) * @param description 分享描述(限制长度不超过 1KB) * @param thumbData 缩略图base64(不能超过32KB) */ public static void shareWeb(String webUrl, int flag, String title, String description, String thumbData) { //初始化一个 WXImageObject 对象,填写分享图片 WXWebpageObject wxImageObject = new WXWebpageObject(); wxImageObject.webpageUrl = webUrl; //用 WXTextObject 对象初始化一个 WXMediaMessage 对象 WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = wxImageObject; msg.title = title; msg.description = description; if (StringUtils.isNotBlank(thumbData)) { String data = thumbData; if (data.contains("base64,")) { data = org.apache.commons.lang3.StringUtils.substringAfter(data, "base64,"); } byte[] bytes = EncodeUtils.base64Decode(data); Bitmap bitmap = ImageUtils.bytes2Bitmap(bytes); msg.setThumbImage(bitmap); } 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的页面。 参考 Android应用接入微信分享,以及遇到的坑-蒲公英云 WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档 Android接入指南 | 微信开放文档 提问之前,请先看提问须知 点击右侧图标发起提问 http://wpa.qq.com/pa?p=2:1053894518:52或者加入QQ群一起学习 TornadoFx学习交流群:1071184701
创建帐户或登录后发表意见