Android微信原生分享网页时加载网络缩略图完美解决

一直以来想记录一下关于项目中遇到的一些问题,方便自己以后查看。

记录关于集成微信原生分享时候加载网络图片遇到的一些问题。

至于怎么注册申请AppID 暂时不在这儿提了 网上很多的例子。

这是微信开放平台中关于微信分享各个类型的地址:

https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Share_and_Favorites/Android.html

从平台可以看出集成微信分享网页很简单几步:

1、将应用的appId注册到微信,其中Conn.WX_APPID是存放APPID的实体类,自己可以建一个实体类来存放APPID,这样在微信登录、支付的时候都可以获取到

private static IWXAPI api;

@Override
    protected View onCreateView() {
        View layout = LayoutInflater.from(getActivity()).inflate(R.layout.home_video_details, null);
        ButterKnife.bind(this, layout);
        api = WXAPIFactory.createWXAPI(getContext(), Conn.WX_APPID, true);
        // 将应用的appId注册到微信
        api.registerApp(Conn.WX_APPID);
        return layout;
    }

2、按照微信官网来写就可以了,当到这以下这步的时候微信官网分享的是本地的图片,那我们分享网络的时候主要是要通过后台返回的图片地址来获取bitmap对象即可

Bitmap thumbBmp = BitmapFactory.decodeResource(getResources(), R.drawable.send_music_thumb);
msg.thumbData =Util.bmpToByteArray(thumbBmp, true);

点击开始分享

/**
     * flag用来区分享都微信还是朋友圈
     * @param flag
     * @param webUrl
     * @param described
     * @param title
     */
    private void toShare(String flag,String webUrl,String described,String title){
        //初始化一个WXWebpageObject,填写url
        WXWebpageObject webpage = new WXWebpageObject();
        webpage.webpageUrl =webUrl;//"网页url"

        //用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage(webpage);
        msg.title =title;//"网页标题"
        msg.description =described;//"网页描述"
        //Glide通过url获取bitmap 进行异步处理结果
        getBitmapImage(imgUrl,flag,msg);
    }

Glide通过url获取bitmap 进行异步处理结果,发生信息到微信进行分享 
 

@SuppressLint("StaticFieldLeak")
    public void getBitmapImage(final String imgUrl,String flag,WXMediaMessage msg) {
        new AsyncTask(){

            @Override
            protected Bitmap doInBackground(Void... voids) {
                Bitmap bitmap = null;
                try {
                    bitmap = Glide.with(getContext())
                            .asBitmap()
                            .load(imgUrl)
                            .submit(100, 100).get();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                msg.thumbData = WXUtil.bmpToByteArray(bitmap, true);
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("webpage");
                req.message = msg;
                ////根据flag判断是微信还是朋友圈
                if (flag.equals("weChat")) {//分享到微信
                    req.scene = SendMessageToWX.Req.WXSceneSession;
                } else if (flag.equals("friends")) {//分享到朋友圈
                    req.scene = SendMessageToWX.Req.WXSceneTimeline;
                }
                api.sendReq(req);
                shareDialog.dismiss();
            }
        }.execute();
    }

WXUtil工具类

public class WXUtil {

    private static final String TAG = "SDK_Sample.Util";

    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

   

    public static byte[] inputStreamToByte(InputStream is) {
        try{
            ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
            int ch;
            while ((ch = is.read()) != -1) {
                bytestream.write(ch);
            }
            byte imgdata[] = bytestream.toByteArray();
            bytestream.close();
            return imgdata;
        }catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }

    

    private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440;
   

    public static int parseInt(final String string, final int def) {
        try {
            return (string == null || string.length() <= 0) ? def : Integer.parseInt(string);

        } catch (Exception e) {
        }
        return def;
    }
}

这样以上主要代码就可以实现分享到微信和朋友圈。

在分享结束返回到当前应用的时候我遇到过从微信返回当前应用点击没有反应,那么我遇到的问题是因为

wxapi包下面的WXEntryActivity  微信回调中没有进行处理 必要要返回的时候关闭WXEntryActivity

  this.finish();//必须要写这句不然 从微信返回当前应用点击就会没有反应

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    // IWXAPI 是第三方app和微信通信的openapi接口
    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //  通过WXAPIFactory工厂,获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(this, Conn.WX_APPID, false);
        //注意:
        //第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
        try {
            api.handleIntent(getIntent(), this);
        } catch (Exception e) {
            e.printStackTrace();
        }    

    }

    
    // 微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq req) {
        
    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    @Override
    public void onResp(BaseResp baseResp) {
       
        String result = null;
        switch (baseResp    .errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result = "分享成功";
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = "分享取消";
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = "分享被拒绝";
                break;
            default:
                result = "分享返回";
                break;
        }
        this.finish();//必须要写这句不然 从微信返回当前应用点击就会没有反应

    }

}

写道这分享到微信和朋友圈就完成了!

获取网络图片的bitmap的方法有很多中没有必要非得这样,我是因为分享结束之后无法再次获取到bitmap,才改用这样的方法来通过Glide 在异步处理的。

也可以这样:

1、其实也可以获取到图片的地址path,

2、把这个地址赋给一个隐藏的图片控件ImageView

Glide.with(this).load(path).into(ImageView);

3、从ImageView中获取Bitmap对象

Bitmap bm =((BitmapDrawable) ((ImageView) image).getDrawable()).getBitmap();

最后我把以上代码从项目中提取做了一个工具类这样我们可以在项目中简单的多次调用不用再写重复代码了

先上工具类ShareUtil

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import com.bumptech.glide.Glide;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import java.util.concurrent.ExecutionException;

/**
 * 描述 微信分享网页工具类
 * by creat wyp 2020/3/13
 */
public class ShareUtil {

    /**
     * 分享到网页携带网络图片
     * @param wxapi
     * @param context
     * @param flag 区别是分享到微信还是朋友圈
     * @param webpageUrl 网页地址
     * @param title 分享标题
     * @param description 分享内容描述
     * @param imgPath  分享携带网络图片地址
     */
    public static void toShareWeb(IWXAPI wxapi, Context context, String flag, String webpageUrl, String title, String description, String imgPath){
        WXWebpageObject webpage = new WXWebpageObject();
        webpage.webpageUrl = webpageUrl;
        WXMediaMessage msg = new WXMediaMessage(webpage);
        msg.title = title;
        msg.description = description;
        //Glide通过url获取bitmap 进行异步处理结果
        initNetWorkImage(wxapi,context,imgPath, flag, msg);
    }

    @SuppressLint("StaticFieldLeak")
    public static void initNetWorkImage(IWXAPI wxapi, Context context, final String imgUrl, String flag, WXMediaMessage msg) {
        new AsyncTask() {

            @Override
            protected Bitmap doInBackground(Void... voids) {
                Bitmap bitmap = null;
                try {
                    bitmap = Glide.with(context)
                            .asBitmap()
                            .load(imgUrl)
                            .submit(100, 100).get();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                msg.thumbData = WXUtil.bmpToByteArray(bitmap, true);
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("webpage");
                req.message = msg;
                if (flag.equals("weChat")) {
                    req.scene = SendMessageToWX.Req.WXSceneSession;
                } else if (flag.equals("friends")) {
                    req.scene = SendMessageToWX.Req.WXSceneTimeline;
                }
                wxapi.sendReq(req);
            }
        }.execute();
    }
    private static String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

}

项目中的调用例如我的:

FragmentA中

private static IWXAPI api;


@Override
protected View onCreateView() {
        View layout = LayoutInflater.from(getActivity()).inflate(R.layout.frt_tab_calculate_home_video_details, null);
        ButterKnife.bind(this, layout);
        api = WXAPIFactory.createWXAPI(getContext(), Conn.WX_APPID, true);
        // 将应用的appId注册到微信
        api.registerApp(Conn.WX_APPID);
        return layout;
    }



//调用
private void test(){
 ShareUtil.toShareWeb(api,getContext(),flag,videUrl,described,description,spare);
}

只需要如下一行就行 在test()中调用这是我自己测试写的,可以根据自身情况调用

ShareUtil.toShareWeb(api,getContext(),flag,videUrl,described,description,spare);

其中的参数在工具类中有介绍,至此就ok了

当然喜欢的可以点个赞,再走!

 

你可能感兴趣的:(Android开发问题解决)