友盟分享與原生微信獲取code衝突解決

前言

因爲歷史遺留問題,項目中微信登陸用的是原生微信的登陸,即先請求 code、再 經過 code 獲取 access_token,而後經過access_token調用接口,獲取微信用戶信息。java

以前項目中用到了友盟分享,在加入微信登陸功能出現了,常常會出現了code been used, hints: [ req_id: FEMAxQaLRa-CSO ]這個問題。api

若是使用友盟獲取微信用戶信息也不會有這個問題,固然若是後臺大佬若是願意改代碼也能夠,可現實...,因而只有咱們本身動手解決了。微信

分析

首先,確認問題出在哪裏?ide

因而,先去掉了友盟分享的相關邏輯,發現正常,基本能夠確認問題出在友盟上。可是,又不能去掉項目中的友盟分享邏輯,是否是能夠判斷是分享時,用友盟的邏輯,若是是登陸時,使用本身的邏輯?this

經過查看微信sdk的源碼,咱們發現,WXEntryActivity 實現了IWXAPIEventHandler,而返回的code的回調是方法onRespurl

public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
  @Override
	public void onResp(BaseResp resp) {
        //這裏
    }
}
複製代碼

而後,咱們去看看友盟sdk的源碼spa

public void a(b var1) {
        SLog.I("WXCallbackActivity 分發回調");
        if (this.a != null && var1 != null) {
            try {
                this.a.getWXEventHandler().a(var1);
            } catch (Exception var3) {
                SLog.error(var3);
            }
        }

        this.finish();
    }

    public void a(a var1) {
        if (this.a != null) {
            this.a.getWXEventHandler().a(var1);
        }

        this.finish();
    }
複製代碼

臥槽,還混淆了,只能硬着頭皮繼續看了 查看b,和微信sdk的對比,發現b即微信sdk 中的BaseResp b源碼,已省略部分代碼code

public abstract class b {
       public void a(Bundle var1) {
        var1.putInt("_wxapi_command_type", this.a());
        var1.putInt("_wxapi_baseresp_errcode", this.a);
        var1.putString("_wxapi_baseresp_errstr", this.b);
        var1.putString("_wxapi_baseresp_transaction", this.c);
        var1.putString("_wxapi_baseresp_openId", this.d);
    }

    public void b(Bundle var1) {
        this.a = var1.getInt("_wxapi_baseresp_errcode");
        this.b = var1.getString("_wxapi_baseresp_errstr");
        this.c = var1.getString("_wxapi_baseresp_transaction");
        this.d = var1.getString("_wxapi_baseresp_openId");
    }
}
複製代碼

BaseResp源碼,已省略部分代碼token

public abstract class BaseResp {

    public void toBundle(Bundle var1) {
        var1.putInt("_wxapi_command_type", this.getType());
        var1.putInt("_wxapi_baseresp_errcode", this.errCode);
        var1.putString("_wxapi_baseresp_errstr", this.errStr);
        var1.putString("_wxapi_baseresp_transaction", this.transaction);
        var1.putString("_wxapi_baseresp_openId", this.openId);
    }

    public void fromBundle(Bundle var1) {
        this.errCode = var1.getInt("_wxapi_baseresp_errcode");
        this.errStr = var1.getString("_wxapi_baseresp_errstr");
        this.transaction = var1.getString("_wxapi_baseresp_transaction");
        this.openId = var1.getString("_wxapi_baseresp_openId");
    }
}
複製代碼

由此,咱們能夠確認,a(b var1) 此方法爲微信的回調方法。接口

而後,咱們再去找找,當咱們發送獲取code的請求時,怎麼取code呢?

if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) {
    SendAuth.Resp authResp = (SendAuth.Resp)resp;
    String code = authResp.code;
}
複製代碼

判斷如是SendAuth.Resp,那就是獲取資料請求,而後只執行咱們本身的邏輯,不然,則執行友盟原有邏輯。 而後就是去找友盟中的SendAuth.Resp類,通過查找,發現是友盟中的com.umeng.weixin.umengwx.i

public void b(Bundle var1) {
        super.b(var1);
        this.e = var1.getString("_wxapi_sendauth_resp_token");
        this.f = var1.getString("_wxapi_sendauth_resp_state");
        this.g = var1.getString("_wxapi_sendauth_resp_url");
        this.h = var1.getString("_wxapi_sendauth_resp_lang");
        this.i = var1.getString("_wxapi_sendauth_resp_country");
    }

    public void a(Bundle var1) {
        super.a(var1);
        var1.putString("_wxapi_sendauth_resp_token", this.e);
        var1.putString("_wxapi_sendauth_resp_state", this.f);
        var1.putString("_wxapi_sendauth_resp_url", this.g);
        var1.putString("_wxapi_sendauth_resp_lang", this.h);
        var1.putString("_wxapi_sendauth_resp_country", this.i);
    }
複製代碼

SendAuth.Resp部分代碼

public void fromBundle(Bundle var1) {
            super.fromBundle(var1);
            this.code = var1.getString("_wxapi_sendauth_resp_token");
            this.state = var1.getString("_wxapi_sendauth_resp_state");
            this.url = var1.getString("_wxapi_sendauth_resp_url");
            this.lang = var1.getString("_wxapi_sendauth_resp_lang");
            this.country = var1.getString("_wxapi_sendauth_resp_country");
        }

        public void toBundle(Bundle var1) {
            super.toBundle(var1);
            var1.putString("_wxapi_sendauth_resp_token", this.code);
            var1.putString("_wxapi_sendauth_resp_state", this.state);
            var1.putString("_wxapi_sendauth_resp_url", this.url);
            var1.putString("_wxapi_sendauth_resp_lang", this.lang);
            var1.putString("_wxapi_sendauth_resp_country", this.country);
        }
複製代碼

其中,i.e即爲咱們須要的code,剩下的就簡單了,修改WXEntryActivity.a(b var)方法

@Override
    public void a(com.umeng.weixin.umengwx.b b) {
       if (b instanceof i) {
          //處理咱們本身的邏輯
        } else {
           super.a(b);
        }
}
複製代碼

問題完美解決。

相關文章
相關標籤/搜索