关于android:AndroidQQ登录接入详细介绍

9次阅读

共计 8446 个字符,预计需要花费 22 分钟才能阅读完成。

一、前言

因为之前本人我的项目的账号零碎不是十分欠缺,所以思考接入 QQ 这个弱小的第三方平台的接入,目前我的项目临时应用 QQ 登录的接口进行后期的测试,这次从搭建到欠缺花了整整两天工夫,不得不吐槽一下 QQ 互联的官网文档,从界面就能够看出了,好几年没培修了,示例代码也写的不是很分明,翻了好多源代码和官网的 demo,这个 demo 能够作为辅助参考,官网文档的 api 生效了能够从外面找相应的代替,但它的代码也太多了,一个 demo 一万行代码,心累,过后把 demo 弄到能够运行就花了不少工夫,很多 api 如同是生效了,笔者本人做了一些解决和欠缺,简直把 sdk 性能列表的登录相干的 api 都尝试了一下,真的相当的坑,注释行将开始,心愿这篇文章可能给后来者一些参考和帮忙。

二、环境配置

1. 获取利用 ID

这个比较简单,间接到 QQ 互联官网申请一个即可,官网地址

https://connect.qq.com

申请利用的时候须要留神利用名字不能呈现违规词汇,否则可能申请不通过

利用信息的填写须要以后利用的包名和签名,这个腾讯这边提供了一个获取包名和签名的 app 供咱们开发者应用,下载地址

https://pub.idqqimg.com/pc/misc/files/20180928/c982037b921543bb937c1cea6e88894f.apk

未通过审核只能应用调试的 QQ 号进行登录,通过就能够面向全副用户了,以下为审核通过的图片

2. 官网下载相干的 sdk

下载地址

https://tangram-1251316161.file.myqcloud.com/qqconnect/OpenSDK_V3.5.10/opensdk_3510_lite_2022-01-11.zip

举荐间接下载最新版本的,不过着实没看懂最新版本的更新布告,说是修复了 retrofit 抵触的问题,而后过后新建的我的项目没有用,后果报错,最初还是加上了,才能够

[图片上传失败 …(image-f70a8f-1647264931314)]

3. jar 的引入

将 jar 放入 lib 包下,而后在 app 同级的 build.gradle 增加以下代码即实现 jar 的援用

dependencies {
    ...
    implementation fileTree(dir: 'libs', include: '*.jar')
    ...
}

4. 配置 Manifest

在 AndroidManifest.xml 中的 application 结点下减少以下的 activity 和启动 QQ 利用的申明, 这两个 activity 无需咱们在另外创立文件,引入的 jar 曾经解决好了

 <application
       ...    
        <!-- 这里的权限为开启网络拜访权限和获取网络状态的权限,必须开启,不然无奈登录 -->
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <activity
            android:name="com.tencent.tauth.AuthActivity"
            android:exported="true"
            android:launchMode="singleTask"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="tencent 你的 appId" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.tencent.connect.common.AssistActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="behind"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.tencent.login.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
        ...
    </application>

下面的哪个代码的最初提供了一个 provider 用于拜访 QQ 利用的,须要另外创立一个 xml 文件,其中的 authorities 是自定义的名字,确保惟一即可,这边最上面那个 provider 是翻 demo 找的,文档没有写,在 res 文件夹中新增一个包 xml,外面增加文件名为 file\_paths 的 xml,其内容如下

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="opensdk_external" path="Images/tmp"/>
    <root-path name="opensdk_root" path=""/>
</paths>

三、初始化配置

1. 初始化 SDK

退出以下代码在创立登录的那个 activtiy 下,不然无奈拉起 QQ 利用的登录界面,至于官网文档所说的须要用户抉择是否受权设施的信息的阐明,这里通用的做法是在利用外部申明一个第三方 sdk 的列表,而后在外面阐明 SDK 用到的相干设施信息的权限

Tencent.setIsPermissionGranted(true, Build.MODEL)

2. 创立实例

这部分倡议放在全局配置,这样能够实现登录异样强制退出等性能

/**
 * 其中 APP_ID 是申请到的 ID
 * context 为全局 context
 * Authorities 为之前 provider 外面配置的值
 */
val mTencent = Tencent.createInstance(APP_ID, context, Authorities)

3. 开启登录

在开启登录之前须要本人创立一个 UIListener 用来监听回调后果(文档没讲怎么创立的,找了良久的 demo)这里的代码为根底的代码,比拟容易实现,目前还没写回调相干的代码,次要是为了疾速展现成果

open class BaseUiListener(private val mTencent: Tencent) : DefaultUiListener() {private val kv = MMKV.defaultMMKV()
    override fun onComplete(response: Any?) {if (response == null) {"返回为空, 登录失败".showToast()
            return
        }
        val jsonResponse = response as JSONObject
        if (jsonResponse.length() == 0) {"返回为空, 登录失败".showToast()
            return
        }
        "登录胜利".showToast()
        doComplete(response)
    }

    private fun doComplete(values: JSONObject?) { }
    override fun onError(e: UiError) {Log.e("fund", "onError: ${e.errorDetail}")
    }

    override fun onCancel() {"勾销登录".showToast()
    }
}

建设一个按钮用于监听,这里进行登录操作

button.setOnClickListener {if (!mTencent.isSessionValid) {
        // 判断会话是否无效
        when (mTencent.login(this, "all",iu)) {
            
            // 上面为 login 可能返回的值的状况
            0 -> "失常登录".showToast()
            1 -> "开始登录".showToast()
            -1 -> "异样".showToast()
            2 -> "应用 H5 登陆或显示下载页面".showToast()
            else -> "出错".showToast()}
    }
}

这边对 mTencent.login(this, “all”,iu) 中 login 的参数做一下解释阐明

mTencent.login(this, "all",iu)
// 这里 Tencent 的实例 mTencent 的 login 函数的三个参数
//1. 为以后的 context,//2. 权限, 可选项,个别抉择 all 即可,即全副的权限,不过目前如同也只有一个凋谢的权限了
//3. 为 UIlistener 的实例对象

还差最初一步,获取回调的后果的代码,activity 的回调,这边显示办法曾经废除了,原本想革新一下的,前面发现要革新的话须要动 sdk 外面的源码,有点麻烦就没有改了,等更新

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)
    // 腾讯 QQ 回调,这里的 iu 依然是相干的 UIlistener
    Tencent.onActivityResultData(requestCode, resultCode, data,iu)
    if (requestCode == Constants.REQUEST_API) {if (resultCode == Constants.REQUEST_LOGIN) {Tencent.handleResultData(data, iu)
        }
    }
}

至此,曾经能够失常登录了,但还有一件咱们开发者最关怀的事件没有做,获取的用户的数据在哪呢?能够获取 QQ 号吗?上面将为大家解答这方面的纳闷。

四、接入流程以及相干代码

首先答复一下下面提出的问题,能够取得两段比拟要害的 json 数据,一个是 login 的时候获取的,次要是 token 相干的数据,还有一段就是用户的个人信息的 json 数据,这些都在 UIListener 中进行解决和获取。第二个问题能不能获取 QQ 号,答案是不能,咱们只能获取与一个与 QQ 号一样具备惟一标记的 id 即 open\_id, 显然这是出于用户的隐衷平安思考的,接下来简述一下具体的登录流程

1. 登录之前查看是否有 token 缓存

  • 有,间接启动主 activity
  • 无,进入登录界面

判断是否具备登录数据的缓存

// 这里采纳微信的 MMKV 进行贮存键值数据
MMKV.initialize(this)
val kv = MMKV.defaultMMKV()
kv.decodeString("qq_login")?.let{val gson = Gson()
    val qqLogin = gson.fromJson(it, QQLogin::class.java)
    QQLoginTestApplication.mTencent.setAccessToken(qqLogin.access_token,qqLogin.expires_in.toString())
    QQLoginTestApplication.mTencent.openId = qqLogin.openid
}

查看 token 和 open\_id 是否无效和 token 是否过期,这里采取不同于官网的举荐的用法,次要是 api 生效了或者是本人没用对办法,总之官网提供的 api 进行缓存还不如 MMKV 键值存 login json 来的切实,也很不便,这里倡议多多应用日志,不便排查谬误

// 这里对于 uiListener 进行了重写,object 的作用有点像 java 外面的匿名类
// 用到了 checkLogin 的办法
mTencent.checkLogin(object : DefaultUiListener() {override fun onComplete(response: Any) {
        val jsonResp = response as JSONObject

        if (jsonResp.optInt("ret", -1) == 0) {val jsonObject: String? = kv.decodeString("qq_login")
            if (jsonObject == null) {"登录失败".showToast()

            } else {// 启动主 activity}
        } else {"登录已过期,请从新登录".showToast()
            // 启动登录 activity

        }
    }

    override fun onError(e: UiError) {"登录已过期,请从新登录".showToast()
        // 启动登录 activity

    }

    override fun onCancel() {"勾销登录".showToast()
    }
})

2. 进入登录界面

在判断 session 无效的状况下,进入登录界面,对 login 登录可能呈现的返回码做一下解释阐明

Login.setOnClickListener {if (!QQLoginTestApplication.mTencent.isSessionValid) {when (QQLoginTestApplication.mTencent.login(this, "all",iu)) {0 -> "失常登录".showToast()
            1 -> "开始登录".showToast()
            -1 -> {"异样".showToast()
                QQLoginTestApplication.mTencent.logout(QQLoginTestApplication.context)
            }
            2 -> "应用 H5 登陆或显示下载页面".showToast()
            else -> "出错".showToast()}
    }
}
  • 1:失常登录

    这个就无需做解决了,间接在回调那里做相干的登录解决即可

  • 0:开始登录

    同失常登录

  • -1:异样登录

    这个须要做一点解决,过后第一次遇到这个状况就是主 activity 异样耗费退回登录的 activity,此时在此点击登录界面的按钮导致了异常情况的呈现,不过这个解决起来还是比拟容易的,执行强制下线操作即可

    "异样".showToast()
    mTencent.logout(QQLoginTestApplication.context)
    
  • 2:应用 H5 登陆或显示下载页面

    通常状况下是未装置 QQ 等软件导致的,这种状况无需解决,SDK 主动封装好了,这种状况会主动跳转 QQ 下载界面

同样的有呈现 UIListener 就须要调用回调进行数据的传输

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)
    // 腾讯 QQ 回调
    Tencent.onActivityResultData(requestCode, resultCode, data,iu)
    if (requestCode == Constants.REQUEST_API) {if (resultCode == Constants.REQUEST_LOGIN) {Tencent.handleResultData(data, iu)
        }
    }
}

3. 进入主 activity

这里须要搁置一个按钮执行下线操作,不便调试,同时这里须要将之前的 token 移除从新获取 token 等数据的缓存

button.setOnClickListener {mTencent.logout(this)
    val  kv = MMKV.defaultMMKV()
    kv.remove("qq_login")
    // 返回登录界面的相干操作
    "退出登录胜利".showToast()}

至此,其实还有一个很重要的货色没有阐明,那就是 token 数据的缓存和个人信息数据的获取,这部分我写的登录的那个 UIlistener 外面了,登录胜利的同时,获取 login 的 response 的 json 数据和个人信息的 json 数据

4. 获取两段重要的 json 数据

  • login 的 json 数据

    这个比拟容易,当咱们登录胜利的时候,oncomplete 外面的 response 即咱们想要的数据

    override fun onComplete(response: Any?) {if (response == null) {"返回为空, 登录失败".showToast()
            return
        }
        val jsonResponse = response as JSONObject
        if (jsonResponse.length() == 0) {"返回为空, 登录失败".showToast()
            return
        }
        // 这个即利用 MMKV 进行缓存 json 数据
        kv.encode("qq_login",response.toString())
        "登录胜利".showToast()}
    
  • 个人信息的数据

    这个须要在 login 无效的前提下能力返回失常的数据

    // 首先须要用上一步获取的 json 数据对 mTencent 进行赋值,这部分放在 doComplete 办法中执行
    private fun doComplete(values: JSONObject?) {
        // 利用 Gson 进行格式化成对象
        val gson = Gson()
        val qqLogin = gson.fromJson(values.toString(), QQLogin::class.java)
        mTencent.setAccessToken(qqLogin.access_token, qqLogin.expires_in.toString())
        mTencent.openId = qqLogin.openid
        Log.e("fund",values.toString())
    }
    

    创立一个 get\_info 办法进行获取,留神这里须要对 mTencent 设置相干的属性能力获取失常获取数据

    private fun getQQInfo(){
        val qqToken = mTencent.qqToken
        // 这里的 UserInfo 是 sdk 自带的类,传入上下文和 token 即可
        val info = UserInfo(context,qqToken)
        info.getUserInfo(object :BaseUiListener(mTencent){override fun onComplete(response: Any?){
                // 这里对数据进行缓存
                kv.encode("qq_info",response.toString())           
            }
        })
    }
    

5. 踩坑系列

这里次要吐槽一下对于腾讯的自带的 session 缓存机制,过后是抱着不必本人实现缓存间接用现成的机制去看的,很遗憾这波偷懒失败,这部分 session 的设置不晓得具体的缓存机制,只晓得大略是用 share preference 实现的,外面有 saveSession,initSession,loadSession 这三个办法,看上去很容易的样子,而后抱着这种心态去尝试了一波,果然不出意外空指针异样,尝试批改了一波回调的程序依然空指针异样,折腾了大略三个多小时,放弃了,心态给搞崩了,最终释然了,为什么要用腾讯提供的办法,这个缓存本人实现也是相当的容易,这时想到了 MMKV,两行代码实现读取,最初只批改了多数的代码实现了登录的 token 的缓存机制,翻看 demo 外面的实现,外面如同是用这三种办法进行实现的,可能是某个实现机制没有弄明确,其实也不想明确,本人的思路比再去看 demo 容易多了,只是多了一个 json 的转对象的过程,其余的没有差异。所以倡议后来者间接本人实现缓存,不必管 sdk 提供的那些办法,真的有点难用。

五、总结

总之这次实现 QQ 接入踩了许多的坑,不过幸好最终还是实现了,心愿腾讯互联这个 sdk 可能上传 github 让更多的人参加和提供反馈,不然这个文档说是最差 sdk 体验也不为过。上面附上这次实现 QQ 登录的 demo 的 github 地址以及相干的 demo apk 供大家进行参考,大略总共就 400 行代码左右比官网的 demo 好很多,有问题欢送留言

https://github.com/xyh-fu/QQLoginTest.git
正文完
 0