Android图片分享问题采坑总结

我们项目中经常会用到微信分享,好友分享,朋友圈分享,收藏等功能,虽然开发了很多遍可能还是遇到各种问题,今天主要整理我在开发中遇到的问题;

1.分享图片问题

开发者在 App 中在集成微信 SDK 后,可调用接口实现,依次支持文字、图片、音乐、视频、网页、小程序类型分享,分享支持参考如下:WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档

今天主要讲讲图片分享我遇到的一些问题,首先了解分享图片的限制如下:

WXMediaMessage (微信媒体消息内容)说明

字段 类型 含义 备注
sdkVer int sdk 版本号
title String 消息标题 限制长度不超过 512Bytes
description String 消息描述 限制长度不超过 1KB
thumbData byte[] 缩略图的二进制数据 限制内容大小不超过 32KB
mediaObject WXMediaMessage.IMediaObject 消息对象 用于描述一个媒体对象的接口,媒体对象包括:
WXTextObject、WXImageObject、WXMusicObject、WXVideoObject、WXWebpageObject、 WXFileObject、WXAppExtendObject、WXMiniProgramObject 等

我主要讲一下thumbData限制的处理方式:

  • 等比压缩图片到指定大小,目的压缩图片大小保持图片可以看清,同时保证不变形;
  • 降低图片质量直到图片大小达到32KB;

为什么分两步呢,而不是只有最后一步呢?防止原图过大,导致压缩时间过长;

实例代码如下:

微信分享图片代码

    /**
     * 分享图片到朋友圈或者好友
     *
     * @param bmp   图片的Bitmap对象
     * @param scene 分享方式:好友还是朋友圈
     */
    public boolean sharePic(Bitmap bmp, int scene) {
        //初始化一个WXImageObject对象
        WXImageObject imageObj = new WXImageObject(bmp);
        //1.设置缩略图
        Bitmap thumb = thumbBmp(bmp, 300,300);
        bmp.recycle();
        return share(imageObj, thumb, scene);
    }

    private boolean share(WXMediaMessage.IMediaObject mediaObject, Bitmap thumb, int scene) {
        return share(mediaObject, null, thumb, null, scene);
    }
    
private boolean share(WXMediaMessage.IMediaObject mediaObject, String title, Bitmap thumb, String description, int scene) {
        //初始化一个WXMediaMessage对象,填写标题、描述
        WXMediaMessage msg = new WXMediaMessage(mediaObject);
        if (title != null) {
            msg.title = title;
        }
        if (description != null) {
            msg.description = description;
        }
        if (MethodUtils.isNotEmpty(thumb) && thumb != null) {
            //2.降低图片质量保证图片分享缩略图不超过32KB
            msg.thumbData = BitmapAndBase64.bmpToByteArray(thumb, 30);
            //msg.setThumbImage(thumb);
        }
        //构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.message = msg;
        req.scene = scene;
        return api.sendReq(req);
    }



微信分享缩略图处理工具类

  /**
     * 等比例缩放指定大小
     * @param bitmap
     * @param with
     * @param height
     * @return
     */
    public static Bitmap thumbBmp(Bitmap bitmap, int with, int height){
        int srcWidth = bitmap.getWidth();
        int srcHeight = bitmap.getHeight();
        double sx = (double) with / srcWidth;
        double sy = (double) height / srcHeight;
        int newWidth = with;
        int newHeight = height;
        // 等比缩放
        if (sx > sy) {
            sx = sy;
            newWidth = (int) (sx * srcWidth);
        } else {
            sy = sx;
            newHeight = (int) (sy * srcHeight);
        }
        Bitmap thumbBmp = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
        return thumbBmp;
    }

     /**
     * Bitmap转换成byte[]并且进行压缩,压缩到不大于maxkb
     *
     * @param bitmap
     * @param maxkb
     * @return
     */
    public static byte[] bmpToByteArray(Bitmap bitmap, int maxkb) {
        Bitmap newBit = bitmap;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        int options = 100;
        newBit.compress(Bitmap.CompressFormat.PNG, options, output);
        while (output.toByteArray().length / 1024 > maxkb && options != 10) {
            //清空output
            output.reset();
            //这里压缩options%,把压缩后的数据存放到output中
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, output);
            options -= 10;
        }
        return output.toByteArray();
    }

分享后缩略图的实际效果图,保证相对清晰,不变形

2.分享出去的图片四个角落有黑边问题(透明边角)

我们可以看下京东的图片分享四个角没有黑色边角问题,应该是分享到微信时处理添加白色背景,仅仅是推测,也看了小红书等软件没有圆角分享效果;

那么我看下怎么处理的

 将我们要分享的View转换为Bitmap代码如下:

   //对View控件里面的内容进行截图
    public static Bitmap testViewSnapshot(View view) {
        //使控件可以进行缓存
        view.setDrawingCacheEnabled(true);
        //获取缓存的 Bitmap
        Bitmap drawingCache = view.getDrawingCache();
        //复制获取的 Bitmap
        drawingCache = Bitmap.createBitmap(drawingCache);

        //关闭视图的缓存
        view.setDrawingCacheEnabled(false);
        return drawingCache;
    }

四个角是透明的,图片透明部分不做处理就是黑色的,那块区域没有颜色;

 我们看下什么都不处理的情况下四个圆角的地方分享到微信以后会有黑角的问题那么怎么处理呢?

那么就是在生成View的Bitmap添加到一个白色Bitmap的上面,两个Bitmap合成一个Bitmap解决了黑角的问题;

    //对View控件里面的内容进行截图
    public static Bitmap testViewSnapshot(View view) {
        //使控件可以进行缓存
        view.setDrawingCacheEnabled(true);
        //获取缓存的 Bitmap
        Bitmap drawingCache = view.getDrawingCache();
        //复制获取的 Bitmap
        drawingCache = Bitmap.createBitmap(drawingCache);

        //关闭视图的缓存
        view.setDrawingCacheEnabled(false);
        //添加白色背景
        Bitmap newBitmap = Bitmap.createBitmap(drawingCache.getWidth(), drawingCache.getHeight(), Bitmap.Config.RGB_565 );
        newBitmap.eraseColor(Color.WHITE);
        Canvas canvas = new Canvas(newBitmap);
        canvas.drawBitmap(drawingCache, 0, 0, null);
        canvas.save();
        // 存储新合成的图片
        canvas.restore();
        //返回合成的图片
        return newBitmap;
    }

看下最终效果如下:

 以上仅仅是项目实际遇到一些问题的解决办法,也欢迎大家提供更好的解决方案

3.WXEntryActivity(按照微信要求在指定路径下定义的Activity)

在WXEntryActivity进行微信分享,登录状态码处理如下:

@Override
    public void onResp(BaseResp baseResp) {
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                if (baseResp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) { //分享
                    L.i("微信分享成功");
                } else if (baseResp.getType() == ConstantsAPI.COMMAND_SENDAUTH) {
                    //拿到了微信返回的code,立马再去请求access_token
                    String code = ((SendAuth.Resp) baseResp).code; //授权code
                    //发送请求获取access_token
                    getAccessToken(code);
                    L.i("微信登陆认证成功");
                }
                WXEntryActivity.this.finish();
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                L.i("微信请求取消");
                //发送广播告知PersonFrament,取消了登陆
                Intent intent = new Intent(IConstants.loginReceiver);
                intent.putExtra("cancel", true);
                sendBroadcast(intent);
                WXEntryActivity.this.finish();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                L.i("微信请求失败");
                WXEntryActivity.this.finish();
                break;
            default:
                WXEntryActivity.this.finish();
                break;
        }
    }

4.微信常见问题处理方法

Q:调用wxapi.sendReq接口,返回true,但微信客户端并未启动,请检查以下几项:

A:    1)微信是否安装

2)调用时的Apk包名和签名是否与开放平台填写的一致,签名请使用该工具:点击下载,常发生在安装了debug版本又安装release版本情况,确定包名签名后卸载微信重装或者清除微信数据再做测试

3)检查发送时的缩略图大小是否超过32k

4)能够调起微信到选择好友列表,但是点击发送后无响应,请检查proguard配置是否对微信SDK代码进行了混淆,建议不要对SDK对混淆,参考以下proguard配置:

-keep class com.tencent.mm.opensdk.** {

*;

}

-keep class com.tencent.wxop.** {

*;

}

-keep class com.tencent.mm.sdk.** {

*;

}

项目根据实际情况自己分析微信未调起来原因;

参考:

WXMediaMessage (微信媒体消息内容)说明 | 微信开放文档(微信分享图片,文字,音乐等内容使用说明)

微信开放文档(微信分享安卓常见问题)

猜你喜欢

转载自blog.csdn.net/ahou2468/article/details/123182839
今日推荐