社會化登陸分享-微信SDK接入

本篇在基於以前封裝的SocialSDK的項目上增長了微信SDK的登陸受權和分享。簡單介紹了微信登陸分享的接入和使用注意java

具體代碼項目Github地址:github.com/tsy12321/So…android

0 系列文章

系列一 Android SDK的二次封裝和使用
系列二 源碼解析
系列三 微信SDK接入
系列四 QQ SDK接入
系列五 新浪微博 SDK接入git

1 官方文檔

微信的官方接入文檔:github

open.weixin.qq.com/cgi-bin/sho…web

2 登陸受權

微信的登陸受權是基於OAuth2.0標準。api

一整套的受權流程官方文檔很清晰:安全

open.weixin.qq.com/cgi-bin/sho…微信

這裏面着重理解幾個概念:app

  1. code 調出微信受權肯定後會返回的code,須要用這個code去換取access_token
  2. access_token 受權成功後都是微信提供的接口都是經過access_token去獲取的。因爲access_token是code+appid+secret請求後獲取的,因此建議客戶端得到到code後,該接口放在服務端進行。(這邊封裝的sdk secret是放在本地,調用比較方便,若是是對安全性要求較高的建議將這個步驟放到服務端進行,客戶端不要存放secret)
  3. refresh_token access_token具備時效性。當access_token失效後能夠經過refresh_token獲取一個新的access_token。可是若是refresh_token過時後,只能再次調用客戶端進行受權。

2.1 Android 接入受權代碼

先初始化wxapi並註冊:ide

this.mWXApi = WXAPIFactory.createWXAPI(context.getApplicationContext(), this.mConfig.appId);
        this.mWXApi.registerApp(this.mConfig.appId);複製代碼

受權登陸時調用:

SendAuth.Req req1 = new SendAuth.Req();
req1.scope = sScope;
req1.state = "snsapi_userinfo,snsapi_friend,snsapi_message";

if(!this.mWXApi.sendReq(req1)) {
    this.mAuthListener.onError(this.mConfig.getName(), "sendReq fail");
    LogUtils.e("wxapi sendReq fail");
}複製代碼

回調結果:

回調處理統一見後面解釋。

3 分享

微信對應5種分享,2個渠道(微信會話、朋友圈)

so!根據分享的媒介類型調用微信不一樣的api。

@Override
    public void share(IShareMedia shareMedia, ShareListener shareListener) {
        this.mShareListener = shareListener;

        WXMediaMessage msg = new WXMediaMessage();
        String type = "";

        if(shareMedia instanceof ShareWebMedia) {       //網頁分享
            ShareWebMedia shareWebMedia = (ShareWebMedia) shareMedia;
            type = "webpage";

            //web object
            WXWebpageObject webpageObject = new WXWebpageObject();
            webpageObject.webpageUrl = shareWebMedia.getWebPageUrl();

            msg.mediaObject = webpageObject;
            msg.title = shareWebMedia.getTitle();
            msg.description = shareWebMedia.getDescription();
            msg.thumbData = BitmapUtils.bitmap2Bytes(shareWebMedia.getThumb());
        } else if(shareMedia instanceof ShareTextMedia) {   //文字分享
            ShareTextMedia shareTextMedia = (ShareTextMedia) shareMedia;
            type = "text";

            //text object
            WXTextObject textObject = new WXTextObject();
            textObject.text = shareTextMedia.getText();

            msg.mediaObject = textObject;
            msg.description = shareTextMedia.getText();
        } else if(shareMedia instanceof ShareImageMedia) {  //圖片分享
            ShareImageMedia shareImageMedia = (ShareImageMedia) shareMedia;
            type = "image";

            //image object
            WXImageObject imageObject = new WXImageObject();
            //image限制10M
            imageObject.imageData = BitmapUtils.compressBitmap(BitmapUtils.bitmap2Bytes(shareImageMedia.getImage()), 10 * 1024 * 1024);

            msg.mediaObject = imageObject;

            //直接縮放圖片
            Bitmap thumb = Bitmap.createScaledBitmap(shareImageMedia.getImage(), 200, 200, true);
            msg.thumbData = BitmapUtils.bitmap2Bytes(thumb);
            thumb.recycle();
        } else if(shareMedia instanceof ShareMusicMedia) {  //音樂分享
            ShareMusicMedia shareMusicMedia = (ShareMusicMedia) shareMedia;
            type = "music";

            WXMusicObject musicObject = new WXMusicObject();
            musicObject.musicUrl = shareMusicMedia.getMusicUrl();

            msg.mediaObject = musicObject;
            msg.title = shareMusicMedia.getTitle();
            msg.description = shareMusicMedia.getDescription();
            msg.thumbData = BitmapUtils.bitmap2Bytes(shareMusicMedia.getThumb());
        } else if(shareMedia instanceof ShareVideoMedia) {      //視頻分享
            ShareVideoMedia shareVideoMedia = (ShareVideoMedia) shareMedia;
            type = "video";

            WXVideoObject videoObject = new WXVideoObject();
            videoObject.videoUrl = shareVideoMedia.getVideoUrl();

            msg.mediaObject = videoObject;
            msg.title = shareVideoMedia.getTitle();
            msg.description = shareVideoMedia.getDescription();
            msg.thumbData = BitmapUtils.bitmap2Bytes(shareVideoMedia.getThumb());
        } else {
            if(this.mShareListener != null) {
                this.mShareListener.onError(this.mConfig.getName(), "shareMedia error");
            }
            return ;
        }

        //壓縮縮略圖到32kb
        if(msg.thumbData != null && msg.thumbData.length > '耀') {        //微信sdk裏面判斷的大小
            msg.thumbData = BitmapUtils.compressBitmap(msg.thumbData, '耀');
        }

        //發起request
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.message = msg;
        req.transaction = buildTransaction(type);

        if(this.mConfig.getName() == PlatformType.WEIXIN) {     //分享好友
            req.scene = SendMessageToWX.Req.WXSceneSession;
        } else if(this.mConfig.getName() == PlatformType.WEIXIN_CIRCLE) {      //分享朋友圈
            req.scene = SendMessageToWX.Req.WXSceneTimeline;
        }

        if(!this.mWXApi.sendReq(req)) {
            if(this.mShareListener != null) {
                this.mShareListener.onError(this.mConfig.getName(), "sendReq fail");
            }
            LogUtils.e("wxapi sendReq fail");
        }
    }複製代碼

分享中注意幾點:

  1. 圖片分享的圖片大小在10M內
  2. 全部的縮略圖要控制在32KB

而後還有一些其餘參數限制能夠參考微信sdk資源下載下來的本地Api文檔。

若是參數錯誤sendReq會返回false,沒法分享。

4 微信結果回調

微信要求項目中定死 wxapi.WXEntryActivity這個文件,回調會調用這個文件。因此咱們自定義了一個WXCallbackActivity,將全部內容寫在這個文件中,而後具體項目中的WXEntryActivity只須要繼承該Activity便可。

WXCallbackActivity見下:

public abstract class WXCallbackActivity extends Activity implements IWXAPIEventHandler {

    protected WXHandler mWXHandler = null;

    public WXCallbackActivity() {

    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SocialApi api = SocialApi.get(this.getApplicationContext());
        this.mWXHandler = (WXHandler)api.getSSOHandler(PlatformType.WEIXIN);
        this.mWXHandler.onCreate(this.getApplicationContext(), PlatformConfig.getPlatformConfig(PlatformType.WEIXIN));
        this.mWXHandler.getWXApi().handleIntent(this.getIntent(), this);
    }

    protected final void onNewIntent(Intent paramIntent) {
        super.onNewIntent(paramIntent);
        SocialApi api = SocialApi.get(this.getApplicationContext());
        this.mWXHandler = (WXHandler)api.getSSOHandler(PlatformType.WEIXIN);
        this.mWXHandler.onCreate(this.getApplicationContext(), PlatformConfig.getPlatformConfig(PlatformType.WEIXIN));
        this.mWXHandler.getWXApi().handleIntent(this.getIntent(), this);
    }

    public void onResp(BaseResp resp) {
        if(this.mWXHandler != null && resp != null) {
            try {
                this.mWXHandler.getWXEventHandler().onResp(resp);
            } catch (Exception var3) {
                ;
            }
        }

        this.finish();
    }

    public void onReq(BaseReq req) {
        if(this.mWXHandler != null) {
            this.mWXHandler.getWXEventHandler().onReq(req);
        }

        this.finish();
    }
}複製代碼

其中發現回調的數據主要是在onResp中處理,而後在WXCallbackActivity中又將最終處理放在了WXHandler中。

WXHandler的回調處理:

public WXHandler() {
    this.mEventHandler = new IWXAPIEventHandler() {
        public void onResp(BaseResp resp) {
            int type = resp.getType();
            switch(type) {
                case ConstantsAPI.COMMAND_SENDAUTH:     //受權返回
                    WXHandler.this.onAuthCallback((SendAuth.Resp)resp);
                    break;

                case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:        //分享返回
                    WXHandler.this.onShareCallback((SendMessageToWX.Resp)resp);
                    break;
            }

        }

        public void onReq(BaseReq req) {
        }
    };
}

//驗證回調
protected void onAuthCallback(SendAuth.Resp resp) {
    switch (resp.errCode) {
        case BaseResp.ErrCode.ERR_OK:       //受權成功
            getAuthWithCode(resp.code);
            break;

        case BaseResp.ErrCode.ERR_USER_CANCEL:      //受權取消
            if(this.mAuthListener != null) {
                this.mAuthListener.onCancel(PlatformType.WEIXIN);
            }
            break;

        default:    //受權失敗
            CharSequence err = TextUtils.concat(new CharSequence[]{"weixin auth error (", String.valueOf(resp.errCode), "):", resp.errStr});
            if(mAuthListener != null) {
                mAuthListener.onError(PlatformType.WEIXIN, err.toString());
            }
            break;
    }
}複製代碼

注意,在回調的一些常量定義中(ConstantsAPI.COMMAND_SENDAUTH、BaseResp.ErrCode.ERR_OK等)都在本地的API中有定義。因此,若是有問題,多看看微信提供的API文檔。

微信本地API文檔
微信本地API文檔

結尾

以上即實現了微信平臺的接入,當接入方須要接入微信部分時,只須要同時將social_sdk.jar和微信的sdk包同時引用進項目,便可調用微信相關的登陸和分享。

本篇結束,後面還會繼續接入其餘平臺。。。

相關文章
相關標籤/搜索