爱笑的星月 發表於 2022-11-1 18:38:00

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

<blockquote>
<p>原文:Android开发 对接微信分享SDK总结 - Stars-One的杂货小窝</p>
</blockquote>
<p>公司项目需要对接微信分享,本来之前准备对接友盟分享的,但友盟的分享实际参数太多,而我又只需要对接一个微信分享,于是便是选择总结对接官方的</p>
<p>顺便把微信SDK的APPID申请的流程也一起记录了</p>
<h2 id="步骤">步骤</h2>
<h3 id="1注册获得appid">1.注册获得APPID</h3>
<p>前往微信公众平台,使用企业认证的开发者账号进行登录,提交应用包名和签名指纹文件,可以生成一个appId,有了此appId账号才能有侯勋的操作</p>
<p>通过输入命令可查看签名文件的md5等信息:</p>
<pre><code>keytool -list -v -keystore qj_test.keystore
</code></pre>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202210/1210268-20221031163915914-1759212029.png" alt="" loading="lazy"></p>
<blockquote>
<p>注意:上述输完命令后需要输入密码,密码不会显示出来,密码正确则会出现下面的相关md5等信息了</p>
</blockquote>
<p>微信平台比较坑的就是,它要求输入不要带<code>:</code>号,且还要小写的md5数值,我们稍微处理一下:我比较懒,就写了几行代码处理了,代码如下:</p>
<pre><code class="language-java">//改为你的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);
</code></pre>
<p>输出结果复制一下,就得到了符合规范的md5了</p>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202210/1210268-20221031170203123-841553343.png" alt="" loading="lazy"></p>
<h3 id="2添加依赖">2.添加依赖</h3>
<pre><code>implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'
</code></pre>
<p>官方文档提供的写法是不固定版本号的,我这里觉得还是固定版本号比较好,需要依赖中央仓库即可</p>
<h3 id="3初始化启动分享">3.初始化启动分享</h3>
<pre><code class="language-java">// 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));

}
</code></pre>
<p>之后在分享的Activity或Application中进行初始化,调用<code>regToWx()</code>,如</p>
<pre><code class="language-java">regToWx(MainActivity.this)
</code></pre>
<blockquote>
<p>PS: 这里可以看下下面提到的工具类封装</p>
</blockquote>
<h3 id="4使用微信分享">4.使用微信分享</h3>
<p>经过上面的步骤,我们已经能够使用微信分享了,使用IWXAPI那个对象即可,具体可以查看文档WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档</p>
<pre><code>api.sendReq(req);
</code></pre>
<p>不过需要注意一下Android11的适配,需要在<code>AndroidManifest.xml</code>声明</p>
<pre><code class="language-xml">&lt;queries&gt;
    &lt;!-- 指定微信包名--&gt;
    &lt;package android:name="com.tencent.mm" /&gt;
&lt;/queries&gt;
</code></pre>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202211/1210268-20221101181650067-1205492507.png" alt="" loading="lazy"></p>
<p>这里我是封装了一个工具类,源码在下一章节,主要封装了分享文本,图片,视频和网页链接,至于分享小程序和分享音乐文件没有需求,就暂时没有对接,各位可以参考的完善即可</p>
<p>这里顺便补充一下,由于我自己个人没法成功申请到微信应用平台的APPID,于是我就是使用了另外项目的的APPID来进行测试</p>
<p>测试的发现,只要你使用同个签名文件,同时,把build.gradle里面的applicationId改成填写的包名,微信分享就是能够正常的使用</p>
<p>举个例子,我们有一个应用包名为<code>com.starsone.test</code>的应用已经申请到了APPID</p>
<p>这个时候,我们另外个项目,包名与其不同,但我们想要测试一下分享功能,可以进行以下的操作:</p>
<p>修改app模块里的build.gradle,将applicationId改为<code>com.starsone.test</code>包名,并使用相同的签名文件打包即可使用同个APPID测试分享功能了,如下图所示:</p>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202211/1210268-20221101182703706-650832898.png" alt="" loading="lazy"></p>
<p>这里如果使用分享视频或分享网页链接,在微信中会以消息卡片的形式展示,如下图所示:</p>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202211/1210268-20221102155436372-649457099.png" alt="" loading="lazy"></p>
<h3 id="5添加回调">5.添加回调</h3>
<p>如果项目中需要对分享成功或失败进行监听,来进行进一步的逻辑处理,可以按照微信官方的文档添加一个WxEntryActivity实现</p>
<p>由于我开发的项目暂时无需,所以没怎么研究,这里稍微简单的补充一下:</p>
<p>我们需要创建一个<code>WXEntryActivity</code>作为回调的接收,<code>WXEntryActivity</code>没有页面,主要实现微信的回调接口<code>IWXAPIEventHandler</code>即可,代码如下:</p>
<pre><code class="language-java">
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    public void onCreate(Bundle savedInstanceState){
      //如果Activity需要回调下面的onResp()方法,则需要调用此方法(api是上面代码创建的对象,需要使用同个对象)
      api.handleIntent(intent,this)
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

    @Override
    public void onResp(BaseResp baseResp) {

    }
}
</code></pre>
<pre><code class="language-xml">&lt;activity
    android:name=".wxapi.WXEntryActivity"
    android:exported="true"
    android:launchMode="singleTask"
    android:taskAffinity="com.tyky.share"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"/&gt;
</code></pre>
<p>这里,注意,Activity是要处于你当前包名下的wxapi文件夹,如我自己的例子,当前包名是<code>com.tyky.share</code>,也是我在新建一层wxapi包名,并将Activity放在里面,如下图所示</p>
<p><img src="https://img2022.cnblogs.com/blog/1210268/202211/1210268-20221101180852246-1892159363.png" alt="" loading="lazy"></p>
<p>这里由于我没有用到,所以就没有在方法里补充对应的逻辑了</p>
<p>逻辑解释如下:</p>
<blockquote>
<p>通过<code>api.sendReq(req)</code>分享内容,发送的请求会将回调一次 <code>onReq()</code> 方法,之后微信分享完成(成功或取消)之后,会将响应结果将回调到 <code>onResp()</code> 方法</p>
</blockquote>
<h2 id="工具类封装">工具类封装</h2>
<p>工具类用到了以下两个依赖,记得先导入</p>
<pre><code>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'
</code></pre>
<blockquote>
<p>PS:微信SDK依赖也不要忘记哦!</p>
</blockquote>
<details>
<summary>点击查看工具类源码</summary>
<pre><code class="language-java">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;

/**
* 参考文档 (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);
    }
}

</code></pre>
</details>
<p>工具类使用的时候,记得在注册的时候一起进行初始化,把上述第三步的初始化方法代码改为如下面:</p>
<pre><code class="language-java">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));
}
</code></pre>
<p>之后在Application或Activity进行初始化,其他步骤不变</p>
<h2 id="踩坑总结">踩坑总结</h2>
<p><strong>1、配置签名的坑</strong></p>
<p>解决:一定要MD5、小写、不要带冒号,最好用官方给的签名获取工具。</p>
<p><strong>2、没有注册API</strong></p>
<p>解决:API是运行重复注册的,并且也不是耗时任务,所以不妨放在Activity的onCreate下面,记得写这个。</p>
<p><strong>3、分享的图标</strong></p>
<p>解决:分享的图标大小不能超过32K,要是jpg格式。</p>
<p><strong>3、分享图标自己能看到,好友看不到</strong></p>
<p>解决:修改分享的标题和内容,不要触及微信的敏感词检测系统,多试几下。</p>
<p><strong>4、没有回调</strong></p>
<p>解决:一定要注意WXEntryActivity的包名路径是否正确,已经配置export=true</p>
<p><strong>5、确定了问题4后还是调不起来</strong></p>
<p>你确定有在WXEntryActivity的onCreate里面注册API并且调用 api.handleIntent(getIntent(), this);? 估计你没有吧?</p>
<p><strong>6、回调到其他页面</strong></p>
<p>解决:没办法直接回调到其他页面,但可以通过广播、EventBus等通知的实现来通知其他页面刷新,同时结束WXEntryActivity的页面。</p>
<h2 id="参考">参考</h2>
<ul>
<li>Android应用接入微信分享,以及遇到的坑-蒲公英云</li>
<li>WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档</li>
<li>Android接入指南 | 微信开放文档</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <hr>
<span>提问之前,请先看</span>提问须知
<span>点击右侧图标发起提问</span>
<img border="0" src="http://wpa.qq.com/pa?p=2:1053894518:52" alt="联系我" title="联系我">
<span>或者加入QQ群一起学习</span>
<img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="Stars-One安卓学习交流群" title="Stars-One安卓学习交流群">
TornadoFx学习交流群:1071184701
<img src="https://img2020.cnblogs.com/blog/1210268/202003/1210268-20200316120825333-1551152974.png" width="1000" height="auto">
<img src="https://img2018.cnblogs.com/blog/1210268/201905/1210268-20190508151523126-971809604.gif" width="1000" height="auto">
<!--<img src="https://img2020.cnblogs.com/blog/1210268/202004/1210268-20200413161422035-1188549898.gif" width="1000" height="auto">--><br><br>
来源:https://www.cnblogs.com/stars-one/p/16848763.html
頁: [1]
查看完整版本: Android开发 对接微信分享SDK总结