Summary of Android picture sharing problems

We often use WeChat sharing, friends sharing, friends circle sharing, collection and other functions in our projects. Although we have developed many times, we may still encounter various problems. Today, I mainly sort out the problems I encountered in the development;

1. The problem of sharing pictures

After integrating the WeChat SDK in the App, developers can call the interface implementation, and support text, picture, music, video, web page, and applet type sharing in turn. The sharing support reference is as follows: WXMediaMessage (WeChat media message content) Description | WeChat Open Documentation ;

Today I mainly talk about some of the problems I have encountered with image sharing. First of all, I will understand the limitations of sharing images as follows:

Description of WXMediaMessage (WeChat media message content)

field Types of meaning Remark
sdkVer int sdk version number
title String message title The limit length does not exceed 512Bytes
description String message description Limit length not more than 1KB
thumbData byte[] Thumbnail binary data Limit content size to 32KB
mediaObject WXMediaMessage.IMediaObject message object An interface used to describe a media object, including:
WXTextObject, WXImageObject, WXMusicObject, WXVideoObject, WXWebpageObject, WXFileObject, WXAppExtendObject, WXMiniProgramObject, etc.

I mainly talk about the handling of thumbData restrictions:

  • Compress the image proportionally to the specified size, and the purpose of compressing the image size is to keep the image clearly visible, and at the same time to ensure that it is not deformed;
  • Reduce the image quality until the image size reaches 32KB;

Why two steps instead of just the last one? Prevent the original image from being too large, resulting in too long compression time;

The example code is as follows:

WeChat share picture code

    /**
     * 分享图片到朋友圈或者好友
     *
     * @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);
    }



WeChat Share Thumbnail Processing Tool

  /**
     * 等比例缩放指定大小
     * @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();
    }

The actual renderings of the thumbnails after sharing are guaranteed to be relatively clear and not deformed

2. There are black borders in the four corners of the shared pictures (transparent corners)

We can see that there are no black corners in the four corners of JD.com's picture sharing. It should be added to the white background when sharing to WeChat. It's just speculation, and we have also seen that software such as Xiaohongshu has no rounded corner sharing effect;

Then I'll see how to deal with it

 The code to convert the View we want to share to Bitmap is as follows:

   //对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;
    }

The four corners are transparent, the transparent part of the picture is black without processing, and that area has no color;

 Let's take a look at the problem of black corners after sharing the four rounded corners on WeChat without processing anything, so how to deal with it?

Then, the Bitmap that generates the View is added to a white Bitmap, and the two Bitmaps are combined into one Bitmap to solve the problem of black corners;

    //对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;
    }

Take a look at the final effect as follows:

 The above are only solutions to some problems encountered by the project, and you are also welcome to provide better solutions ;

3. WXEntryActivity (Activity defined under the specified path according to WeChat requirements)

For WeChat sharing in WXEntryActivity, the login status code is processed as follows:

@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. WeChat FAQ

Q: The wxapi.sendReq interface is called and returns true, but the WeChat client is not started. Please check the following items:

A: 1) Is WeChat installed?

2) Whether the Apk package name and signature when calling are the same as those filled in the open platform, please use this tool for signature: Click to download , which often happens when the debug version is installed and the release version is installed. After confirming the package name and signature, uninstall WeChat and reinstall or clear it. WeChat data re-test

3) Check if the thumbnail size when sending is more than 32k

4) You can call up WeChat to select the friend list, but there is no response after clicking send. Please check whether the proguard configuration confuses the WeChat SDK code. It is recommended not to confuse the SDK pair. Refer to the following proguard configuration:

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

*;

}

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

*;

}

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

*;

}

According to the actual situation, the project analyzes the reasons why WeChat has not been activated;

refer to:

WXMediaMessage (WeChat media message content) Instructions | WeChat Open Documents (WeChat sharing pictures, text, music and other content instructions)

Wechat Open Document (Wechat Sharing Android FAQ)

Guess you like

Origin blog.csdn.net/ahou2468/article/details/123182839
Recommended