记录Android微信分享功能的吐槽与思考

在App内潜入分享到微信好友或朋友圈的功能想必大家已经屡见不鲜了,比如Android分享一个网页信息(URL)到微信客户端的代码:

 /**
 * 微信分享:分享网页
 * @param context
 * @param url
 * @param title
 * @param description
 * @param scene
 */
 public static void shareToWeChatWithWebpage(Context context, String url,
 String title, String description, int scene){
 IWXAPI iwxapi = WXAPIFactory.createWXAPI(context, WXEntryActivity.WXAPI_APP_ID);
 if (!iwxapi.isWXAppInstalled()){
 ToastManager.getInstance(context.getApplicationContext()).showToast("您尚未安装微信客户端");
 return;
 }
 WXWebpageObject wxWebpageObject = new WXWebpageObject();
 wxWebpageObject.webpageUrl = url;
 WXMediaMessage wxMediaMessage = new WXMediaMessage(wxWebpageObject);
 wxMediaMessage.mediaObject = wxWebpageObject;
 wxMediaMessage.title = title;
 wxMediaMessage.description = description;
 wxMediaMessage.thumbData =
 ImageManager.bmpToByteArray(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_share_invite), true);
 SendMessageToWX.Req req = new SendMessageToWX.Req();
 req.transaction = String.valueOf(System.currentTimeMillis());
 req.message = wxMediaMessage;
 req.scene = scene;
 iwxapi.sendReq(req);
 }

虽然已经在不同的App内使用了N遍,但在最近的一个项目中还是出了错:执行完这段代码,应用没有任何反应,无法调起微信客户端,并且没有任何错误信息打印提示。不得已查看官方资料 —— [Android常见问题],找到这样一段提示:

Q:调用wxapi.sendReq接口,返回true,但微信客户端并未启动,请检查以下几项:
A:
 1)微信是否安装
 2)调用时的Apk包名和签名是否与开放平台填写的一致,签名请使用该工具:点击下载,常发生在安装了debug版本又安装release版本情况,确定包名签名后卸载微信重装或者清除微信数据再做测试
 3)检查发送时的缩略图大小是否超过32k
 4)能够调起微信到选择好友列表,但是点击发送后无响应,请检查proguard配置是否对微信SDK代码进行了混淆,建议不要对SDK对混淆,参考以下proguard配置:
 -keep class com.tencent.mm.sdk.** {
 *;
}

经检查,发现代码iwxapi.sendReq(req);执行过后返回了false,其实按照上面Q&A的写法,已经不属于该问题范畴了。但是还是照着这四点检查了一遍,发送的缩略图本地预览大小只有不到20KB,其他配置也没有问题,可还是出错,到底问题出在哪里了呢?
 纠结,沉思,差点就怀疑人生了!最后冒着试一试的态度,我把缩略图换成一张不到7KB的小图,再次执行代码,结果惊人地发现:iwxapi.sendReq(req);返回true,并成功调起微信客户端!当时心中一万头草泥马奔腾而过啊!
 一番激动之后,就开始研究了,为什么之前使用的缩略图没有超过官网文档32K的限制,却无法调起微信客户端呢,难道官网文档写错了,上限不是32KB?于是回归源码,打开微信SDK提供的类WXMediaMessage,找到如下定义的一系列常量:

public static final int THUMB_LENGTH_LIMIT = 32768;
private static final int TITLE_LENGTH_LIMIT = 512;
private static final int DESCRIPTION_LENGTH_LIMIT = 1024;
private static final int MEDIA_TAG_NAME_LENGTH_LIMIT = 64;
private static final int MESSAGE_ACTION_LENGTH_LIMIT = 2048;
private static final int MESSAGE_EXT_LENGTH_LIMIT = 2048;

果不其然,微信SDK对于分享到微信的缩略图大小、标题长度、描述长度等信息都做了限制。其中,缩略图大小限制为32768,源码中并没有注释写明单位。好奇的我将其除以1024,刚好得到32,这不就是官网文档提到的上限值32KB嘛(说明源码中的数值单位为Byte)!那就是说官网文档没有写错,可是问题出在哪儿了呢?
 其实事关图片的实际硬盘占用大小和内存占用大小问题。存放在电脑硬盘中的图片文件,会根据不同图片格式的压缩规则进行压缩,从而减少硬盘占用大小,比如常见如JPEG这种有损压缩的图片格式。而在Android系统中,将图像读取到内存当中所占用的内存大小与图片存放在硬盘当中的实际大小没有一点关系,可能更大,也可能更小,使用如下代码即可获取图像所占用的内存大小:

 private Bitmap decodeResource(Resources resources, int id) {
TypedValue value = new TypedValue();
resources.openRawResource(id, value);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inTargetDensity = value.density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, id, opts);
Log.i("Bitmap", "size is " + bitmap.getRowBytes() * bitmap.getHeight());
return bitmap;
}

其中,bitmap.getRowBytes() * bitmap.getHeight()获取的便是Bitmap的内存占用大小,单位为Byte,再除以1024,便可以转换为BK单位。注意:上述从资源中获取Bitmap对象的过程,并没有直接使用decodeResource(Resources res, int id)含带两个参数的方法,是为了避免由于图片存放在不同drawable或者mipmap文件夹下导致的内存占用不一致问题,对Android屏幕适配有所了解的朋友应该懂得这个,这里就不细说了,大家可以参考凯子哥的一篇文章 —— [关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析]。
 通过PS工具,修改缩略图尺寸大小,然后通过上面这段代码测试不同大小的图片在Android手机中所占用的内存大小,同时查看是否可以调起微信客户端。经过这样的测试,最终发现,微信SDK和官方文档中的32KB缩略图上限大小指的是内存占用大小,而非图片的硬盘占用大小。这样,也就解决了前面我所遇到的问题。
 最后,还是得吐槽一下Android微信SDK的诟病,也是一些包括支付宝SDK在内其他第三方服务供应商的通用问题,别无他意,仅作发泄:
 •签名唯一性
 做Android开发的都知道,开发过程中编译打包并运行在手机或模拟器上的apk文件使用的是IDE提供的默认通用签名,而正式上线发布的apk文件使用的是开发人员自定义的正式签名文件。微信SDK在注册应用时只能输入一个签名信息,导致必须在正式包中测试微信SDK相关功能,而正式包又无法做到跟踪调试,非常不方便。当然你也可以这样做,处于开发阶段时,在微信开放平台注册测试包的签名信息,上线时再修改成正式签名文件信息;或者你也可以修改IDE的默认签名文件。但是这些都不是很方便,如果微信开放平台能够像其他一些第三方服务供应商一样,针对一个应用提供两个或多个签名信息的注册,岂不快哉。
 •文档不清晰
 很多大型的第三方服务供应商只管功能的提供,不管文档的说明,甚至连Samples代码都写的乱七八糟的,导致我们开发人员在使用过程中连个完整的参考说明都没有,出了问题也无从下手,白白浪费很多不必要的时间和精力。

文章有些啰嗦,主要是阐述了自己这次在开发微信分享时遇到问题、分析问题并解决问题的过程,希望给大家一些借鉴。

(0)

相关推荐

  • Android开发:微信授权登录与微信分享完全解析

    前言 在移动互联网浪潮中,联网APP已经把单机拍死在沙滩上,很多公司都希望自家应用能够有一套帐号系统,可是许多用户却并不一定买账:我凭啥注册你家应用的帐号?微博,微信,QQ几乎成了每个人手机中的必装应用,于是微信,微博,QQ说了:来来来,你们都可以用我家的帐号登录你家应用,只要你遵循OAuth2.0协议标准就行.于是第三方社交帐号登陆成为了许多新兴应用的选择,由于腾讯官方微信开放平台的在线文档相对最新的SDK有些出入,并且登录相关的文档结构次序有些紊乱,今天就把我的一些经验记录在此,对微信开放平

  • Android应用接入微信分享的实例代码

    最近项目中要接入微信分享,记录下接入流程 注册应用信息并下载必要工具 在微信开放平台注册应用信息 下载 签名生成工具获取待接入应用的签名 应用信息填入签名 注意:由于一般调试签名和正式签名不一致,测试时可填入测试包的签名,上线时需要改为正式包的签名 接入 在build.gradle中,添加如下依赖: dependencies { compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+' } 或: dependencies { c

  • Android应用中加入微信分享简单方法

    一.申请你的AppID http://open.weixin.qq.com/ 友情提示:推荐使用eclipse打包软件最后一步的MD5值去申请AppID 二.官网下载libammsdk.jar包 http://open.weixin.qq.com/download/?lang=zh_CN 三.将libammsdk.jar复制到工程的libs目录 四.在需要分享的Activity编写代码 复制代码 代码如下: private IWXAPI wxApi;  //实例化  wxApi = WXAPIF

  • Android编程实现微信分享信息的方法

    本文实例讲述了Android编程实现微信分享信息的方法.分享给大家供大家参考,具体如下: 随着微信越来越火,越来越多的应用要求有分享到微信的功能.虽然有很多平台都帮集成有分享功能,比如友盟.但是个人觉得友盟集成的东西太多了,自己封装得太过分了,很多资源文件也要带进去,所以感觉不是怎么好,所以自己也研究了一下微信的调用其SDK分享.下面说说步骤. 第一:下载官方的sdk demo. 下载地址:http://open.weixin.qq.com/download/?lang=zh_CN 第二:解压,

  • Android实现微信分享带有缩略图的网页

    前言 最近做了一个web app 需要做微信分享. 需求是分享web页还要带有图片,并且图片还不是本地的,这就有点坑了, 也就是说图片还要从网络实时获取并且是同步的,如果是异步的还需要等待(用户体验就不好了) 代码如下 /** * 微信分享 好友 */ public void wxHyShare(String shareUrl, String title, String image, String desc) { IWXAPI api = WXAPIFactory.createWXAPI(con

  • 记录Android微信分享功能的吐槽与思考

    在App内潜入分享到微信好友或朋友圈的功能想必大家已经屡见不鲜了,比如Android分享一个网页信息(URL)到微信客户端的代码: /** * 微信分享:分享网页 * @param context * @param url * @param title * @param description * @param scene */ public static void shareToWeChatWithWebpage(Context context, String url, String titl

  • vue单应用在ios系统中实现微信分享功能操作

    表示是第一次使用vue做单应用显目,也是在逐渐的摸索中~更是各种踩坑,各种填坑,打算写博客么?是因为不想写笔记了,嗯嗯 就是这么简单 进入正题. 刚开始做微信分享的这个功能的时候,脑补了官方文档微信JS-SDK说明文档 基础的知识不多说了,反正多看文档总是没错的~在安卓系统上面分享是没出错的,但是在ios上面问题就来了,表示无限吐槽ios,但是吐槽归吐槽,问题总是该解决的-在网上百度了很多vue单应用在ios系统中实现微信分享失败的原因以及解决方案 原因 单页面应用通过什么入口进去的 url保持

  • Flutter实现仿微信分享功能的示例代码

    目录 1.首先去pub官网 2 在微信开放平台注册开发者账号以及创建你的应用程序 3 在分享页面 3.1 初始化 3.2 检测微信是否安装 3.3 分享微信消息 总结 本文设计到的知识点有 主要问题 Flutter 用来快速开发 Android iOS平台应用,在Flutter 中,通过 fluwx或者fluwx_no_pay 插件来实现微信分享功能 主要还是看自己的需求,本示例我将按照没有支付的实现.至于为什么,主要是ios打包提审比较麻烦. 那么接下来就看一下如何实现吧, 1.首先去pub官

  • Java编程调用微信分享功能示例

    本文实例讲述了Java编程调用微信分享功能.分享给大家供大家参考,具体如下: 这篇文章介绍如何使用java开发微信分享功能,因为工作,已经开发完成,可使用. 如果想要自定义微信的分享功能,首先在自己的页面内首先使用AJAX.下面我具体举例. 首先是在页面内写入请求后台的AJAX /** * 调用微信分享接口 * */ public void WXConfig(){ String url = getPara("href"); WXConfigController scan = new W

  • JS中静态页面实现微信分享功能

    微信分享网页的时候,希望分享出来的链接是标题+描述+缩略图,微信开发代码示例里已提供了方法,但只适用于动态页面.我使用phpcms把页面生成了静态文件,示例代码就起不到作用了.在网上找了下,有大神使用ajax实现静态页面也能实现微信分享功能,在这里分享给大家. 前台代码: <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> url=locatio

  • Android微信抢红包功能的实现原理浅析

    快到过农历年了,微信红包也越来越多了,出现了好多红包外挂程序,就很好奇如何实现的,于是自己研究了一番,亲自写了个微信抢红包的APP.现在就一步一步来实现它. 实现思路 微信抢红包程序开启时候,他就可以随时识别.捕获红包,服务可以实现正在功能,当我们开启服务的时候,服务就不停的在后台运行,不停地轮询着微信里面的消息,当发现红包时候就立即打开微信红包所在的界面.但是他怎识别红包呢?需要找到微信抢红包里面节点的view,当找到对应的view,在获取view的关键字或者id,根据关键字或者id,自动的模

  • vue实现微信分享功能

    本文实例为大家分享了vue实现微信分享功能的具体代码,供大家参考,具体内容如下 1.引入微信js <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> 2.从后台获取签名并分享 fenxiangFun(){//详情分享 var that = this; this.$http({ url:this.changeDa

  • vue-cli构建项目下使用微信分享功能

    一.index.html中引入微信官方分享js <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> 二.在src下的assets/js文件夹下新建wx.jsapi.js文件,把分享做成公用方法 使用axios来发送请求,参照 //www.jb51.net/article/141008.htm 配置vue-cl

  • vue项目中实现的微信分享功能示例

    本文实例讲述了vue项目中实现的微信分享功能.分享给大家供大家参考,具体如下: /* 微信分享 */ Vue.prototype.wechatShare = (shareData) => { let resource = { title: '随我心愿!', desc: '体验优质服务', link: 'https://www.abc.cn/', img: 'https://www.abc.cn/images/share_logo.jpg' } let obj = Object.assign({}

  • Android实现分享功能

    Android应用中能很方便的完成这些功能,很多的应用中都有"分享"功能?如何分享呢?下面给大家说说看. 最近有人问到Android分享功能用那个比较好,使用Android自带的Intent来进行分享还是借助第三方呢,直接上代码: 一.使用Intent直接和第三方应用进行通信: /** * 分享功能 * * @param context * 上下文 * @param activityTitle * Activity的名字 * @param msgTitle * 消息标题 * @para

随机推荐