Android开发丶集成微信原生分享并于分享网页时加载网络缩略图

微信分享也是一项很常用的功能了,以往都是用友盟或者mobShareSDK框架来实现的,这两者在微信官方的sdk基础上封装的很好,并且加入了一些很实用性的功能,不过这次因为只有微信平台的分享,而且微信登录也是基于微信官方的原生SDK的,所以我们就不用再去大费周章地使用友盟和mobsharesdk了,而且也可以学习些新的东西,经过一番折腾调试,成功地把分享集成成功了,期间也遇到了一些坑,而且微信官方的文档确实不太友好,因此这里对其进行下总结归纳。

有关微信原生登录的请看我另一篇博文

https://blog.csdn.net/u014078990/article/details/83752223

还是效果图走起来:

Android开发丶集成微信原生分享并于分享网页时加载网络缩略图_第1张图片Android开发丶集成微信原生分享并于分享网页时加载网络缩略图_第2张图片

Android开发丶集成微信原生分享并于分享网页时加载网络缩略图_第3张图片

怎么样,不错吧,下来详述实现流程。

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();
}

当检测到有安装微信客户端,开始后续的方法。

当分享网页时,一般会由这三种控件构成,标题,描述,缩略图

Android开发丶集成微信原生分享并于分享网页时加载网络缩略图_第4张图片

那么问题来了,标题和描述官方都给了相应的参数设置,没什么问题,但是缩略图官方仅支持加载本地的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);

Android开发丶集成微信原生分享并于分享网页时加载网络缩略图_第5张图片

有了,有了,红框的就是!

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值,无法调起微信客户端,主要看流程即可)

资源下载

 

 

你可能感兴趣的:(Android)