因爲歷史遺留問題,項目中微信登陸用的是原生微信的登陸,即先請求 code
、再 經過 code
獲取 access_token
,而後經過access_token
調用接口,獲取微信用戶信息。java
以前項目中用到了友盟分享,在加入微信登陸功能出現了,常常會出現了code been used, hints: [ req_id: FEMAxQaLRa-CSO ]
這個問題。api
若是使用友盟獲取微信用戶信息也不會有這個問題,固然若是後臺大佬若是願意改代碼也能夠,可現實...,因而只有咱們本身動手解決了。微信
首先,確認問題出在哪裏?ide
因而,先去掉了友盟分享的相關邏輯,發現正常,基本能夠確認問題出在友盟上。可是,又不能去掉項目中的友盟分享邏輯,是否是能夠判斷是分享時,用友盟的邏輯,若是是登陸時,使用本身的邏輯?this
經過查看微信sdk的源碼,咱們發現,WXEntryActivity 實現了IWXAPIEventHandler
,而返回的code的回調是方法onResp
url
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);
}
}
複製代碼
問題完美解決。