1. 程式人生 > >Android開發第三方登入--微信登入

Android開發第三方登入--微信登入

QQ登入、微信登入,新浪微博登入資料獲取demo下載

    http://download.csdn.net/detail/pkandroid/9903796

github地址 進入

    https://github.com/HYVincent/Login

專案有需求,需要使用微信登入,QQ登入看這裡  Android端要使用微信登入,必須在微信開發平臺建立APP並且稽核通過

如圖: 這裡寫圖片描述 有個地方需要注意的是,在建立APP的時候最好保持名稱一致,而且建立APP的時候簽名是小寫的,並且沒有:符號 ,例如: 這裡寫圖片描述 微信獲取簽名的工具:點選下載  微信登入文件地址:點選檢視  微信登入相關SDK整合:點選檢視

  微信SDK整合:  分為包含統計功能和不包含統計功能的  包含統計功能:

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

不包含統計功能的

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

微信登入LoginActivity.java


public class LoginActivity extends BaseActivity implements ILoginView.View {

    .......
    .........

    /**
     * 微信登入相關
     */
    private IWXAPI api;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        hintTitle();
        ....
        ..........
        //通過WXAPIFactory工廠獲取IWXApI的示例
        api = WXAPIFactory.createWXAPI(this,Config.APP_ID_WX,true);
        //將應用的appid註冊到微信
        api.registerApp(Config.APP_ID_WX);
    }


  .....
  ........


    @OnClick({R.id.login_tv_register, R.id.login_btn_go, R.id.login_tv_forget_password,R.id.iv_other_login_qq,R.id.iv_other_login_sina,R.id.iv_other_login_wx})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            ......
            ..........
            /**
snsapi_base屬於基礎介面,若應用已擁有其它scope許可權,則預設擁有snsapi_base的許可權。使用snsapi_base可以讓移動端網頁授權繞過跳轉授權登入頁請求使用者授權的動作,直接跳轉第三方網頁帶上授權臨時票據(code),但會使得使用者已授權作用域(scope)僅為snsapi_base,從而導致無法獲取到需要使用者授權才允許獲得的資料和基礎功能。
*/
            case R.id.iv_other_login_wx:
                SendAuth.Req req = new SendAuth.Req();
                req.scope = "snsapi_userinfo";//
//                req.scope = "snsapi_login";//提示 scope引數錯誤,或者沒有scope許可權
                req.state = "wechat_sdk_微信登入";
                api.sendReq(req);
                break;

                .......
        }
    }

    ..........
    ...........
}

然後編寫微信登入的回撥頁面:WXEntryActivity.java  在包名的目錄下建立wxapi子包(必須,這個包名必須是配置清單的package值),比如我的包名是:com.vincent.colud.那麼WXEntryActivity.java類完整路徑就是com.vincent.colud.wxapi.WXEntryActivity, 這裡寫圖片描述 另外關於WXEntryActivity註冊必須設定exported屬性為true,否則無法回撥,注意啦 這裡寫圖片描述  現在來看看WXEntryActivity.java

/**
 * description :
 * project name:CCloud
 * author : Vincent
 * creation date: 2017/6/9 18:13
 *
 * @version 1.0
 */

public class WXEntryActivity extends BaseActivity implements IWXAPIEventHandler{

    /**
     * 微信登入相關
     */
    private IWXAPI api;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //通過WXAPIFactory工廠獲取IWXApI的示例
        api = WXAPIFactory.createWXAPI(this, Config.APP_ID_WX,true);
        //將應用的appid註冊到微信
        api.registerApp(Config.APP_ID_WX);
        ViseLog.d("------------------------------------");
        //注意:
        //第三方開發者如果使用透明介面來實現WXEntryActivity,需要判斷handleIntent的返回值,如果返回值為false,則說明入參不合法未被SDK處理,應finish當前透明介面,避免外部通過傳遞非法引數的Intent導致停留在透明介面,引起使用者的疑惑
        try {
            boolean result =  api.handleIntent(getIntent(), this);
            if(!result){
                ViseLog.d("引數不合法,未被SDK處理,退出");
                finish();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        api.handleIntent(data,this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
        finish();
    }

    @Override
    public void onReq(BaseReq baseReq) {
        ViseLog.d("baseReq:"+ JSON.toJSONString(baseReq));
    }

    @Override
    public void onResp(BaseResp baseResp) {
        ViseLog.d("baseResp:"+JSON.toJSONString(baseResp));
        ViseLog.d("baseResp:"+baseResp.errStr+","+baseResp.openId+","+baseResp.transaction+","+baseResp.errCode);
        String result = "";
        switch(baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result ="傳送成功";
                showMsg(1,result);
                finish();
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = "傳送取消";
                showMsg(2,result);
                finish();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = "傳送被拒絕";
                showMsg(1,result);
                finish();
                break;
            default:
                result = "傳送返回";
                showMsg(0,result);
                finish();
                break;
        }

    }
}

另外需要注意的是,以上所有的操作都是在打正式簽名證書的情況下使用  現在已經完成了微信登入的授權,然後開始微信個人資料的獲取  —————————–2017年6月10日08:54:03———————————  這是授權成功之後返回的資料,格式化之後如下:


{
    "code":"0712DRee0kzwiz13fUce0900feRet",
    "country":"CN",
    "errCode":0, 
    "lang":"zh_CN",
    "state":"wechat_sdk_微信登入",
    "type":1,
    "url":"wxb363a9ff53731258://oauth?code=0712DRee0kzwiz13fUce0900fe02DRet&ate=wechat_sdk_%E5%BE%AE%E4%BF%A1%E7%99%BB%E5%BD%95"
}
解釋: 
errCode:
 //ERR_OK = 0(使用者同意) ERR_AUTH_DENIED = -4(使用者拒絕授權 ERR_USER_CANCEL = -2(使用者取消)
code:使用者換取access_token的code,僅在ErrCode為0時有效
state:第三方程式傳送時用來標識其請求的唯一性的標誌,由第三方程式呼叫sendReq時傳入,由微信終端回傳,state字串長度不能超過1K
lang:微信客戶端當前語言
country:微信使用者當前國家資訊

現在來獲取微信的access_token,獲取地址是:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
請求方式:GET
  • 1
  • 2

引數說明:  appid:應用唯一標識,在微信開放平臺提交應用稽核通過後獲得  secret:應用金鑰AppSecret,在微信開放平臺提交應用稽核通過後獲得  code:填寫第一步獲取的code引數  grant_type:固定值,寫authorization_code

獲取WeiXin的Access_token

OkHttpUtils.get().url("https://api.weixin.qq.com/sns/oauth2/access_token")
                        .addParams("appid",Config.APP_ID_WX)
                        .addParams("secret",Config.APP_SECRET_WX)
                        .addParams("code",entity.getCode())
                        .addParams("grant_type","authorization_code")
                        .build()
                        .execute(new StringCallback() {
                            @Override
                            public void onError(okhttp3.Call call, Exception e, int id) {
                                closeDialog();
                            }

                            @Override
                            public void onResponse(String response, int id) {
                                ViseLog.d("response:"+response);

                            }
                        });

響應資料:

{
    "access_token":"hSTsG7nq8e0yEFhOZFT-wAdTsjT9jC0AYvGRiqGwwR6Hko99o_mmYR8KO18kMxeDOz33d9tnBhMzu_NLsIha2HqvTm1OGPL1weBdvXZVFFc",
    "expires_in":7200,
    "refresh_token":"AeN69M27vttqCedxoIOSeY6cxvbt1N584HjEOclUXtNWxRaZWgmtfvn2jWIDX4tq5t-7Btlc1UkEyyFhV7HVIMXe-V6RPjoZdF525vLzev8",
    "openid":"olmt4wfxS21G4VeeVX16_zUhZezY",
    "scope":"snsapi_userinfo",
    "unionid":"o5aWQwAa7niCIXhAIRBOwglIJ7UQ"
}

access_token:介面呼叫憑證  expires_in :access_token介面呼叫憑證超時時間,單位(秒)  refresh_token 使用者重新整理access_token  openid 授權使用者唯一標識  scope 使用者授權的作用域,使用逗號(,)分隔

重新整理或續期access_token使用

介面說明  access_token是呼叫授權關係介面的呼叫憑證,由於access_token有效期(目前為2個小時)較短,當access_token超時後,可以使用refresh_token進行重新整理,access_token重新整理結果有兩種:

1.若access_token已超時,那麼進行refresh_token會獲取一個新的access_token,新的超時時間;

2.若access_token未超時,那麼進行refresh_token不會改變access_token,但超時時間會重新整理,相當於續期access_token。

refresh_token擁有較長的有效期(30天),當refresh_token失效的後,需要使用者重新授權,所以,請開發者在refresh_token即將過期時(如第29天時),進行定時的自動重新整理並儲存好它。

請求方法  使用/sns/oauth2/access_token介面獲取到的refresh_token進行以下介面呼叫:

http請求方式: GET

引數說明  引數 是否必須 說明  appid 是 應用唯一標識  grant_type 是 填refresh_token  refresh_token 是 填寫通過access_token獲取到的refresh_token引數

上面的是從文件上直接複製的,重新整理或續期access_token我暫時沒有嘗試

獲取個人資訊

獲取個人資訊的介面如下:


https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
請求方式:GET

引數就不說了,就那麼樣..


  //https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
        OkHttpUtils.get()
                .url("https://api.weixin.qq.com/sns/userinfo")
                .addParams("access_token",accessTokenEntity.getAccess_token())
                .addParams("openid",accessTokenEntity.getOpenid())//openid:授權使用者唯一標識
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(okhttp3.Call call, Exception e, int id) {
                        closeDialog();
                    }

                    @Override
                    public void onResponse(String response, int id) {
                        ViseLog.d("userInfo:"+response);
                    }
                });

獲取個人資訊響應結果格式化如下:


{
    "openid":"olmt4wfxS24VeeVX16_zUhZezY",
    "nickname":"李文星",
    "sex":1,
    "language":"zh_CN",
    "city":"Shenzhen",
    "province":"Guangdong",
    "country":"CN",
    "headimgurl":"http://wx.qlogo.cn/mmopen/ajNVdqHZLLDickRibe5D4x2ADgSfianmA4kK9hY4esrvGhmAFCe5wjox6b6pL4ibiblKnxibzVtGdqfa2UVHACfmmUsQ/0",
    "privilege":[

    ],
    "unionid":"o5aWQwAa7niCIXhAIRBOwglIJ7UQ"
}