Android分享集成系列之微信分享

作者: dboy_sl | 来源:发表于2017-10-20 17:00 被阅读2441次

    项目中单独集成微信分享,集成起来还算顺利,但是还是有一些坑需要注意。下面我来说说这个具体的过程:

    集成流程

    1.申请你的AppID
    2.下载SDK及API文档
    3.搭建开发环境
    4.在代码中使用开发工具包
    总之,具体参考微信开放平台的接入流程,严格按照流程进行集成。点击查看集成地址

    代码实现

    在具体讲解代码实现前,保证你已经做到以下几点,测试才能通过:

    • 应用已经通过审核
    • 创建的应用包名与项目包名一致

    开始实现

    (1)添加依赖:
    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
    }
    

    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
    }
    

    (其中,前者包含统计功能)

    (2)清单文件权限申明:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    (3)将应用注册到微信:

    要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的APP_ID。(可以在程序入口Activity的onCreate回调函数处,或其他合适的地方将你的应用id注册到微信)

    public void regToWeiXin() {
            wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID, true);
            wxapi.registerApp(appID);
        }
    
    (4)分享到微信:
    1. 判断当前设备是否安装微信:
    /**
         * 判断是否安装微信
         */
        public boolean isWeiXinAppInstall() {
            if (wxapi == null)
                wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID);
            if (wxapi.isWXAppInstalled()) {
                return true;
            } else {
                Toast.makeText(WRKApplication.getContext(), R.string.no_install_wx, Toast.LENGTH_SHORT).show();
                return false;
            }
        }
    
    1. 如果已安装,判断当前版本号对分享的支持情况:
    不同微信版本对开放平台接口的支持(New)

    发送信息:4.0及以上版本微信iPhone、Android客户端;
    接收/查看信息:4.0及以上版本微信iPhone、Android、Sybiam客户端;
    发送到朋友圈:4.2及以上版本微信iPhone、Android客户端;
    收藏到我的收藏:5.0及以上版本微信iPhone、Android客户端。

    判断版本:(这个方法只判断是否支持分享到朋友圈,其他判断类似)

    /**
         * 是否支持分享到朋友圈
         */
        public boolean isWXAppSupportAPI() {
            if (isWeiXinAppInstall()) {
                int wxSdkVersion = wxapi.getWXAppSupportAPI();
                if (wxSdkVersion >= TIMELINE_SUPPORTED_VERSION) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    
    1. 分享数据:(支持文本、图片、表情、音频、视频、url链接、小程序)
    • 分享文本:
    /**
         * 分享文本类型
         *
         * @param text 文本内容
         * @param type 微信会话或者朋友圈等
         */
        public void shareTextToWx(String text, int type) {
            if (text == null || text.length() == 0) {
                return;
            }
    
            WXTextObject textObj = new WXTextObject();
            textObj.text = text;
    
            WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = textObj;
            msg.description = text;
    
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = buildTransaction("text");
            req.message = msg;
            req.scene = type;
    
            getWxApi().sendReq(req);
        }
    
    • 分享图片(代码中开启一个线程用来加载网络图片,显示缩略图)
    /**
         * 分享图片到微信
         */
    
        public void shareImageToWx(final String imgUrl, String title, String desc, final int wxSceneSession) {
            Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
            WXImageObject imgObj = new WXImageObject(bmp);
    
            final WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = imgObj;
            msg.title = title;
            msg.description = desc;
            final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
            bmp.recycle();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream imageStream = getImageStream(imgUrl);
                        Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                        msg.mediaObject = new WXImageObject(bitmap);
                        thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                        bitmap.recycle();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
    
                    SendMessageToWX.Req req = new SendMessageToWX.Req();
                    req.transaction = buildTransaction("img");
                    req.message = msg;
                    req.scene = wxSceneSession;
                    getWxApi().sendReq(req);
                }
            }).start();
        }
    
    • 分享音频:
    /**
         * 分享音乐
         *
         * @param musicUrl       音乐资源地址
         * @param title          标题
         * @param desc           描述
         * @param wxSceneSession
         */
        public void shareMusicToWx(final String musicUrl, final String title, final String desc, final String iconUrl, final int wxSceneSession) {
            WXMusicObject music = new WXMusicObject();
            music.musicUrl = musicUrl;
    
            final WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = music;
            msg.title = title;
            msg.description = desc;
    
            Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
            final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
            bmp.recycle();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream imageStream = getImageStream(iconUrl);
                        Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                        thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                        bitmap.recycle();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
                    SendMessageToWX.Req req = new SendMessageToWX.Req();
                    req.transaction = buildTransaction("music");
                    req.message = msg;
                    req.scene = wxSceneSession;
                    getWxApi().sendReq(req);
                }
            }).start();
        }
    
    • 分享视频:
    /**
         * 分享视频
         *
         * @param videoUrl       视频地址
         * @param title          标题
         * @param desc           描述
         * @param wxSceneSession
         */
    
        public void shareVideoToWx(String videoUrl, String title, String desc, final String iconUrl, final int wxSceneSession) {
            WXVideoObject video = new WXVideoObject();
            video.videoUrl = videoUrl;
    
            final WXMediaMessage msg = new WXMediaMessage(video);
            msg.title = title;
            msg.description = desc;
            Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
            final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
            bmp.recycle();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream imageStream = getImageStream(iconUrl);
                        Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                        thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                        bitmap.recycle();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
    
                    SendMessageToWX.Req req = new SendMessageToWX.Req();
                    req.transaction = buildTransaction("video");
                    req.message = msg;
                    req.scene = wxSceneSession;
                    getWxApi().sendReq(req);
                }
            }).start();
        }
    
    • 分享链接:
    /**
         * 分享url地址
         *
         * @param url            地址
         * @param title          标题
         * @param desc           描述
         * @param wxSceneSession 类型
         */
        public void shareUrlToWx(String url, String title, String desc, final String iconUrl, final int wxSceneSession) {
    
            WXWebpageObject webpage = new WXWebpageObject();
            webpage.webpageUrl = url;
            final WXMediaMessage msg = new WXMediaMessage(webpage);
            msg.title = title;
    
            msg.description = desc;
            Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
            final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
            bmp.recycle();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream imageStream = getImageStream(iconUrl);
                        Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                        thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                        bitmap.recycle();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
                    SendMessageToWX.Req req = new SendMessageToWX.Req();
                    req.transaction = buildTransaction("webpage");
                    req.message = msg;
                    req.scene = wxSceneSession;
                    getWxApi().sendReq(req);
                }
            }).start();
        }
    

    这几种分享已经满足项目需求,所以没有做小程序分享。如果有需要直接参看开发平台Demo即可。

    (5)分享后接受微信的回调:WXEntryActivity类实现
    • 在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(必须确保申请时的包名下,否则接收不到信息)
    • 在manifest文件里面加上exported属性,设置为true
    <activity
                android:name=".wxapi.WXEntryActivity"
                android:exported="true"
                android:theme="@style/AppTheme.Fullscreen.Translucent" />
    

    回调接受处理:

    public class WRKWxEntryActivity extends Activity implements IWXAPIEventHandler {
        private IWXAPI api;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // 通过WXAPIFactory工厂,获取IWXAPI的实例
            api = WRKShareUtil.getInstance().getWxApi();
            //注意:
            //第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
            try {
                api.handleIntent(getIntent(), this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
    
            setIntent(intent);
            api.handleIntent(intent, this);
        }
    
        @Override
        public void onReq(BaseReq baseReq) {
    //        System.out.println(baseReq);
        }
    
        @Override
        public void onResp(BaseResp baseResp) {
            int result;
            switch (baseResp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    result = R.string.errcode_success;
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL:
                    result = R.string.errcode_cancel;
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED:
                    result = R.string.errcode_deny;
                    break;
                case BaseResp.ErrCode.ERR_UNSUPPORT:
                    result = R.string.errcode_unsupported;
                    break;
                default:
                    result = R.string.errcode_unknown;
                    break;
            }
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
            finish();
        }
    }
    

    到这基本上就实现分享功能了,如果这样,那你就厉害了。这里我再说一下在集成时遇到的问题:

    集成问题与解决:

    1. 点击分享后,出现 “ 不合法的参数,无法分享到微信。返回到没有审核的应用 ” ,出现这个问题是因为我把APP_ID写错了。APP_ID一般为一个以wx开头的18个字符的字符串。
    2. 分享了多条数据,发现有几条数据点击分享,不能把微信调起来。这个时候你就需要查看你分享的数据是否符合微信规定的限制条件。要对应限制条件,进行处理。来看一下源码:(检查发送时的缩略图大小是否超过32k)
    final boolean checkArgs() {
            if(this.getType() == 8 && (this.thumbData == null || this.thumbData.length == 0)) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData should not be null when send emoji");
                return false;
            } else if(this.thumbData != null && this.thumbData.length > '耀') {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData is invalid");
                return false;
            } else if(this.title != null && this.title.length() > 512) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, title is invalid");
                return false;
            } else if(this.description != null && this.description.length() > 1024) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, description is invalid");
                return false;
            } else if(this.mediaObject == null) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaObject is null");
                return false;
            } else if(this.mediaTagName != null && this.mediaTagName.length() > 64) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaTagName is too long");
                return false;
            } else if(this.messageAction != null && this.messageAction.length() > 2048) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageAction is too long");
                return false;
            } else if(this.messageExt != null && this.messageExt.length() > 2048) {
                Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageExt is too long");
                return false;
            } else {
                return this.mediaObject.checkArgs();
            }
        }
    

    看看你没有分享成功的原因有没有这些,要是仔细看日志的伙伴应该也能发现这个问题。所以我在代码中做出了处理:

     String title = mShareData.getTitle();
     if (title != null && title.length() > 512)
            title = title.substring(0, 511);
     String desc = mShareData.getDesc();
     if (desc != null && desc.length() > 1024)
           desc = desc.substring(0, 1023);
    

    总结:

    最终集成成功了,遇到的问题也基本解决了。微信的集成与其他的集成大致看一下,套路都是一样的。想一想要是集成其他的,遇到的这些坑,其他分享应该也会有。比如说限制条件。

    由于项目有多个端(APP_ID有多个),都需要分享功能。所以把分享功能放到了公共库,但是这样公共库不能访问到各个端的APP_ID,所以我将APP_ID放到各个端的清单文件中,以mete_data的形式在运行时动态获取。如果不懂这一流程,可以看我的一篇文章:运行时动态获取清单数据

    微信分享工具类,下载地址

    希望这个分享能对你有帮助,收尾!

    相关文章

      网友评论

        本文标题:Android分享集成系列之微信分享

        本文链接:https://www.haomeiwen.com/subject/vdfvuxtx.html