Android探索与巩固(微信QQ第三方登录填坑)

@TOCjava

前言

​ 上个周到如今一直在忙年前的优化任务,领导都是越到年末越想激发你的潜力,任务一个一个地来,干完了就能回家。做为一个刚刚进入这家公司的Android独苗,接触陌生的代码而且周围人没办法提供帮助的状况下在这么短期开发几个功能,仍是挺费神的。等到如今才彻底收工,有时间闲下来去总结一下上个周把我折磨得死去活来的小妖精们。(示例大部分依旧是kotlin)android

微信三方登陆

​ 集成微信的三方登录过程不难,可是中间有好多大坑官方没有说明白。咱们先从头看开始讲,遇到的坑就放在后面详细探讨一下。ios

  1. 注册微信开放平台用户,申请应用。后端

    这一步应该不用说太多,就是简单的注册流程。不过在Android应用这,app的签名是经过微信提供的签名工具获取的:GenSignature,在这里面输入本机已经安装的应用包名,就能获取到这个应用的签名。填上就好了。审核上面说是七个工做日,其实几个小时就好了。api

  2. 引入第三方包,初始化缓存

引入三方包,老规矩微信

com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+
复制代码

在项目的gradle文件中引用这个地址,更新一下就可使用了。app

而后进行初始化,通常要放在Application里面进行:ide

val appID = "wxecb9abc374b780c2"
val api: IWXAPI = WXAPIFactory.createWXAPI(this, appID, true)
private fun initWx() {
   api.registerApp(appID)
}
复制代码

固然这一步不少人直接放在须要调用登录的Activity或者Fragment里面进行,不过我们这里防止之后还须要加微信其余功能,就放在这里了。工具

  1. 接下来就是在Activity或者Fragment里面的操做。

    private fun startWxLogin() {
        val appID = "wxecb9abc374b780c2"
        val api: IWXAPI = WXAPIFactory.createWXAPI(this, appID, true)
        if (!api.isWXAppInstalled) {
            showShort("您还未安装微信")
        } else {
            val req = SendAuth.Req()
            req.scope = "snsapi_userinfo"
            req.state = "zhys_wxlogin"
            api.sendReq(req)
        }
    }
    复制代码

    这个方法就是调起微信的操做,将这个方法放进相应的点击事件里面就行了。req.scope固定为这个,req.state自定。

  2. 接下来须要新建一个类用于接收微信传回来的信息。由于在微信官网注册了包名和签名,因此微信是经过用绝对路径的方式将信息传到这个类里面,这个类有严格的命名规则。必须是包名的一级子目录下新建一个文件夹:wxapi,在这个文件夹下新建名为WXEntryActivity的类,官网给出的规则必须是:包名.wxapi.WXEntryActivity,好比说官网注册为com.androidproject.test,那么这个类的包名就应该是com.androidproject.test.wxapi.WXEntryActivity。下面是这个类的基本写法

class WXEntryActivity : Activity(), IWXAPIEventHandler {
    private var mWeixinAPI: IWXAPI? = null
    private val RETURN_MSG_TYPE_LOGIN = 1
    private val RETURN_MSG_TYPE_SHARE = 2

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mWeixinAPI = WXAPIFactory.createWXAPI(this, WEIXIN_APP_ID, true)
        mWeixinAPI!!.handleIntent(this.intent, this)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        mWeixinAPI!!.handleIntent(intent, this)//必须调用此句话
    }

    //微信发送的请求将回调到onReq方法
    override fun onReq(req: BaseReq) { LogUtils.d("onReq")
    }

    //发送到微信请求的响应结果
    override fun onResp(resp: BaseResp) {
        LogUtils.d("onResp")
        when (resp.errCode) {
            BaseResp.ErrCode.ERR_OK -> {
                LogUtils.d("ERR_OK")
                //发送成功
                val sendResp = resp as SendAuth.Resp
                val code = sendResp.code
                EventBus.getDefault().post(code,"wxCode")
                finish()
            }
            BaseResp.ErrCode.ERR_USER_CANCEL -> {
                if (resp.type == RETURN_MSG_TYPE_SHARE){
                    showShort("分享失败")
                }else{
                    showShort("登录失败")
                }
                LogUtils.e("ERR_USER_CANCEL")
            }
            BaseResp.ErrCode.ERR_AUTH_DENIED -> LogUtils.e("ERR_AUTH_DENIED")
            else -> {
                showShort("微信登录错误")
                LogUtils.d("微信登录错误"+" "+resp.errCode+resp.errStr)
                finish()
            }
        }//发送取消
        //发送被拒绝
        //发送返回

    }
    companion object {
        private val APP_SECRET = "305c1e604e79f7e9b4c9a617c67c345c"
        val WEIXIN_APP_ID = "wxecb9abc374b780c2"
        private val uuid: String? = null
    }

}
复制代码
  1. 这里咱们只用到了微信返回的code,而后发送给后端,后端再集成微信三方登陆的功能获取咱们的用户信息,若是是想取到相关用户信息也是能够取到的。

好了,到如今为止,微信的基本用法就这么多,下面来说一下我在微信集成的时候遇到的

一开始,我按照官网一步步写完运行以后发现微信调起界面只是一闪而过,调起瞬间又关闭,而后在WXEntryActivity这个类中debug也没有触发。显然,微信没有找到这个类。因而我检查了包名,和官网如出一辙,而后我又检查签名,发现debug模式安装和打包安装的签名是不同的。这就很坑,因而我得出结论,以后打包以后再测试吧。可是!!!!改了签名以后仍是不行,网上查找解决办法都说包名不对。但是我左看右看包名彻底一致啊,而后这个问题困扰了我一天。到了晚上回到家精疲力尽的时候,想要作最后一博,就去试验各类方法。而后我发现了这个代码以前设计的是在不一样环境下打包添加不一样的后缀,

applicationIdSuffix ".develop"
复制代码

这个时候大家确定觉得我在这个地方犯了低级错误,去找和官网注册的相同后缀的包名问题就解决了(我却是但愿如此),事实证实问题并非那么简单。

在这里插入图片描述

找到相同包名觉得能够松一口气的时候,绝望地发现仍是不行。我这个时候就感受确定和这行代码有关系,网上成功的案例都是绝对固定的包名。因而我注释掉这行代码,将微信注册的包名换成没有后缀的形式,果真成功了。(心里一万个草泥马奔腾而过)。虽然成功了,可是这个项目不能这么继续作下去,由于以后还要作QQ登录,腾讯开放平台的包名是不能修改的,并且还用了其余的第三方SDK,会影响其余功能。我就只能更改目录结构,硬生生把那个后缀写死在里面。而后切出另一个分支,维持原有的目录结构,保证其余功能能够在测试环境测试。

微信登录的坑

  1. 注意包名是否一致

  2. debug运行的签名和打包签名不一致(集成以后若是出现微信返回ERR=-6的错误,多半是签名不一致,就是这个缘由。也有多是以前微信运行过错误的签名,就会记录到微信缓存中,须要清除缓存或者直接卸载重装)

  3. //applicationIdSuffix ".develop"
    //signingConfig signingConfigs.release
    复制代码

不能使用这两行代码(后面这个是我实验出来的),比较懊恼的是至今不知道其缘由,但愿有缘人看到这篇文章能够解答一下。

QQ三方登陆

接下来咱们讲一下QQ三方登陆,QQ三方登陆其实很简单,我在这个地方绊倒纯粹是经验不足。

QQ三方登录的SDK仍是用的依赖lib包的形式实现。在官网下载它的lib包,引入后就可使用了。

  1. 首先在你须要调用的地方进行实例化:

    val mTencent: Tencent = Tencent.createInstance("你的appid", applicationContext)
    复制代码

    而后进行拉起QQ登录:

    mTencent.login(this, "all", BaseUiListener())
    复制代码

    这里的BaseUiListener是本身去写的接收qq的回调。须要本身去写一下.

  2. 编写QQ回调

    public class BaseUiListener implements IUiListener {
        //注意测试须要在腾讯开放平台注册调试者QQ号
        @Override
        public void onComplete(Object response) {
            try {
    // String openId = ((JSONObject) response).getString("openid");
    // String expires = ((JSONObject) response).getString("expires_in");
                String token = ((JSONObject) response).getString("access_token");
                LogUtils.d(((JSONObject) response).getString("access_token"));
                EventBus.getDefault().post(token,"qqToken");
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void onError(UiError e) {
            LogUtils.d("code:" + e.errorCode + ", msg:"
                    + e.errorMessage + ", detail:" + e.errorDetail);
        }
    
        @Override
        public void onCancel() {
            LogUtils.d("onCancel");
        }
    
    }
    复制代码

这里我只须要qq的accessToken,全部就取了这个值,其余的我的信息也能够取到。

QQ须要注意的点就是在测试环境下须要去腾讯开放平台注册调试者QQ号,否则的话只会不断地从新拉起没有反应。(奇怪的是,ios不用注册也能够收到,由于这个我一直没注意这个问题)。

至此,微信QQ三方登录的坑就算填完了,这些坑耽误了我太长时间,不过也值得。下面再讲一个和主题无关的小坑:

我中间还用了百度的离线语音合成,可是出现一个问题,打正式的包的时候语音就没法读出。我就去锁定了打包的那几行代码得出如下结论:

// minifyEnabled false
// shrinkResources false
复制代码

这两行不能随便加上,收缩资源和缩小文件会去删掉它认为没用的资源文件。极大可能会误删,因此致使了离线语音不可用。

最后总结

​ 前段时间时间太紧张了,博客也没更,本身维护的项目也没作,后面再慢慢跟上吧。踩过的这些坑虽然耗时长,可是涨了很多经验,之后就不会犯错了。

相关文章
相关标签/搜索