微信分享也是一项很常用的功能了,以往都是用友盟或者mobShareSDK框架来实现的,这两者在微信官方的sdk基础上封装的很好,并且加入了一些很实用性的功能,不过这次因为只有微信平台的分享,而且微信登录也是基于微信官方的原生SDK的,所以我们就不用再去大费周章地使用友盟和mobsharesdk了,而且也可以学习些新的东西,经过一番折腾调试,成功地把分享集成成功了,期间也遇到了一些坑,而且微信官方的文档确实不太友好,因此这里对其进行下总结归纳。
有关微信原生登录的请看我另一篇博文
https://blog.csdn.net/u014078990/article/details/83752223
还是效果图走起来:
怎么样,不错吧,下来详述实现流程。
1.首先当然是去微信开放平台申请应用的appid和appkey了,这里我不再详述了。
2.新建wxapi包和WXEntryActivity及相关继承重写我在发布的《Android开发丶集成微信原生登录》这篇博文里已经有了说明,不再复述。
3.首先打开WXEntryActivity写微信分享的回调
这里比较重要的一点是(敲黑板!!!)
微信分享和微信登录的回调都走的onResp()方法,所以我们要加以辨别,否则会混淆一团,好在官方已经返回了相应的type值供我们判断
//请求回调结果处理
@Override
public void onResp(BaseResp baseResp) {
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
switch (baseResp.getType()){
case ConstantsAPI.COMMAND_SENDAUTH:
String code = ((SendAuth.Resp) baseResp).code;
getAccessToken(code);
Log.d("fantasychongwxlogin", code.toString()+ "");
break;
case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:
Log.d("Fan22", "分享成功");
Toast.makeText(getApplicationContext(), "分享成功", Toast.LENGTH_SHORT).show();
finish();
break;
default:
break;
}
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED://用户拒绝授权
finish();
break;
case BaseResp.ErrCode.ERR_USER_CANCEL://用户取消
finish();
break;
default:
finish();
break;
}
}
4.回到启动分享的入口
这里以最常见的分享web网页为例
首先肯定是判断设备是否安装微信了
if (!api.isWXAppInstalled()) {
Toast.makeText(WebViewActivity.this, "您的设备未安装微信客户端", Toast.LENGTH_SHORT).show();
}
当检测到有安装微信客户端,开始后续的方法。
当分享网页时,一般会由这三种控件构成,标题,描述,缩略图
那么问题来了,标题和描述官方都给了相应的参数设置,没什么问题,但是缩略图官方仅支持加载本地的bitmap
如果我们实际需求中是个图片url怎么办?
办法当然是有的,考虑后我们决定把这个网络图片下载到本地保存成bitmap不就可以了。(我太特么机智了)
5.这里就涉及到下载图片了,该方法调用时要放在子线程中,之后再通过runOnUiThread()方法操作UI线程即可,相关代码附上
/**
* 把网络资源图片转化成bitmap
* @param url 网络资源图片
* @return Bitmap
*/
public static Bitmap GetLocalOrNetBitmap(String url) {
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL(url).openStream(), 1024);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, 1024);
copy(in, out);
out.flush();
byte[] data = dataStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
data = null;
return bitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static void copy(InputStream in, OutputStream out)
throws IOException {
byte[] b = new byte[1024];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
private String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
6.我们先检测下该网络图片是否保存成本地bitmap了,先用个imageview检测下
iv.setImageBitmap(bitmap);
有了,有了,红框的就是!
7.接下来设置相关分享参数
那么问题又来了,如果因为网络或者某些不可描述的问题导致图片没下下来咋整?
完全不慌,检测是否为空,如果空的话,加载本地的就可以了。
if (bitmap== null){
bitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round);
}
接下来设置标题,网页等参数
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = "http://www.baidu.com";
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = "这是网页标题";
msg.description = "这是网页描述";
将bitmap进行裁剪,赋值
thumbBmp = Bitmap.createScaledBitmap(bitmap, 150, 150, true);
if (bitmap != null && !bitmap.isRecycled()) {
bitmap = null;
}
msg.thumbData = Util.getBitmapBytes(thumbBmp, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
//根据type设置分享情景
switch (type) {
case TYPE_WECHAT:
//分享到微信好友
req.scene = SendMessageToWX.Req.WXSceneSession;
break;
case TYPE_WECHAT_MOMENT:
//分享到微信朋友圈
req.scene = SendMessageToWX.Req.WXSceneTimeline;
break;
}
api.sendReq(req);
以上代码中,req.scene是设置分享对象的,决定微信好友还是朋友圈,因此我们可以通过在不同的入口传递不同的参数进行判断,决定分享的对象。
showShare(TYPE_WECHAT);
showShare(TYPE_WECHAT_MOMENT);
这里说明一下遇到的一些现象和问题:
1.如果不配置APPID和APPSECRET,微信客户端无法调起
private static final String APP_ID = "";//空值
解决办法:在申请到正式的APPID,可以先使用其余通过审核的应用的APPID值,新建一个测试项目与那个通过审核的应用的包名一致,签名文件一致,保证微信能正常调起以及流程正常跑通,之后把相关代码移植到正式项目中,最后在正式项目中更换正式APPID即可。
2.当微信未登陆时,点击分享可以调起客户端到登陆界面,登陆完成后一闪而过回到应用界面,无法分享到好友或者朋友圈。
解决办法:当前的配置的APPID值与包名不匹配。更换正式APPID值即可。
3.下载bitmap的方法GetLocalOrNetBitmap()必须在子线程中运行。
至此全部完成,demo附上!(因为某些不可描述的原因,本DEMO没有APPID和APPSECRET值,无法调起微信客户端,主要看流程即可)
资源下载