友盟分享与原生微信获取code冲突解决

前言

由于历史遗留问题,项目中微信登录用的是原生微信的登录,即先请求 code、再 通过 code 获取 access_token,然后通过access_token调用接口,获取微信用户信息。

之前项目中用到了友盟分享,在加入微信登录功能出现了,经常会出现了code been used, hints: [ req_id: FEMAxQaLRa-CSO ]这个问题。

如果使用友盟获取微信用户信息也不会有这个问题,当然如果后台大佬如果愿意改代码也可以,可现实...,于是只有我们自己动手解决了。

分析

首先,确认问题出在哪里?

于是,先去掉了友盟分享的相关逻辑,发现正常,基本可以确认问题出在友盟上。但是,又不能去掉项目中的友盟分享逻辑,是不是可以判断是分享时,用友盟的逻辑,如果是登录时,使用自己的逻辑?

通过查看微信sdk的源码,我们发现,WXEntryActivity 实现了IWXAPIEventHandler,而返回的code的回调是方法onResp

public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
  @Override
	public void onResp(BaseResp resp) {
        //这里
    }
}
复制代码

然后,我们去看看友盟sdk的源码

  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源码,已省略部分代码

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源码,已省略部分代码

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);
        }
}
复制代码

问题完美解决。

转载于:https://juejin.im/post/5cd4f753e51d453a543f9e47

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值