黑暗中,追寻那微亮的曙光。

前言
某天翻阅极光文档时,发现极光也推出了一键登录,先来看个效果图:

之前有幸体验了 Mob 的一键登录,而今来体验下极光的一键登录,扫描二维码想下载个 Demo 体验玩一波,尴尬的是,扫出了维护中,本站暂时关闭,艾玛😓😓😓。此问题已反馈极光工作人员。

说句实在话,而今的互联网变更速度,简直让人目不暇接,单单从用户体验来讲,着实让人各种眼光一亮,闪闪冒金星。现在还能记得 Android 4.x 版本的大黑主题,五彩斑斓的黑色。😂😂😂
回到正题上,单纯从用户登录而言,同样也是各种迭代升级,不断的进化,不断的提升用户友好度。从传统手机号码 + 验证码方式,当现在三方登录,再到而今的一键登录,很庆幸,可以感受互联网带来的魅力。
回顾下传统登录方式,也就是通过手机号码 + 验证码的优势:
- 操作简单: 输入手机号,输入验证码,即可通过,简单快捷;
- 知晓人多: 至少我回村大爷大妈都知道大部分软件都可以直接通过手机号 + 验证码方式直接注册,然后就可以随便玩了。
再来说说个人认为的劣势吧。
- 验证码短信不及时: 很多时候都会出现这么一种情况,点击了验证码,也开始了倒计时,但是手机迟迟接受不到验证码的信息,着急的时候真心很无奈,尤其高峰期;
- 手残党易输入错误: 单纯个人而言,很多时候会尴尬的输入错误,然后包括到现在为止,每次输入验证码都要小心翼翼并且一个个校对很多次。😂😂😂
当然以上仅仅是个人使用过程中个人理解,也欢迎各位交流学习。
那么这个一键登录,相比传统又具有什么优势呢?
- 显而易见的,从用户输入手机号、发送验证码、验证验证码有效性,直接升级到只需要点个按钮即可完成上述三步操作;
- 针对后台而言,也省略了对接第三方发送短信 SDK 、提供前端接口以及验证前端发送数据有效性;
- 针对前端而言,用户一步操作即可替换原有三步操作,且直接可以拿到有效手机号,省去很多 Code,何乐而不为?并且再也不需要挨个找运营商官方文档挨个痛苦集成了。
小伙伴说了,你看了吗,你就胡咧咧。好,哥儿们我给你附上三大运行商的链接:
三大运营商地址已附上,不服的小伙伴随时查阅~
其实,万物归根,根本还是简单了。大道归一,大道为简,才是真理。花里胡哨搞了 n 多,仅仅就是注册登录,除非死铁粉,不然至少个人直接 Say Bye or 跳过。
实践
说的天花烂坠,不如真正实践一波。何况好东西,谁不想赶快体验一波?感受下它带来的魅力呢?

一、翻阅极光,简单了解
此物诞生于 18 年,天呐,我现在才知道:

打开极光关于认证介绍,简单截个图:
目前已支持平台:
- Android
- iOS
未支持(包含尚未开放)平台:
- Web (仅支持中国移动以及中国电信,还需要联系商务)
- Flutter (未支持,热门的呀,咋会不支持的呢)
二、移步 Android SDK 集成指南
首先极光官网创建个项目,其次记得配置对应平台所需信息,这里为大家附上截取官网的一个说明:

关键信息已红线标明。
随后我们开始设置 Android 应用包名以及应用签名,如下图所示:

这里单独注明下之前记录的获取 MD5 方式:
之后配置我们的一键登录 RSA 加密公钥:

关于 RSA 加密公钥,可自己代码生成,也可以直接使用在线网址直接生成,将公私钥保存下来即可,简单方便快捷:
比如我在这里使用的非对称加密公钥:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBsfT9nfWqRs1Z10m1U7znvGwE
8ddPsRUvSurJaSV7jxEVVZUUiUoeK1lh+fVOoMAosxCEv+iqQDysUHR52QcPTXEv
Mv0wp5YlCHIj7xckKVU2jxl49zVmaUxhvUXH1C9dbkOBGRtSt9bC7TkvYtVa4X3n
Xh0+GMBQ8MNNBfywSwIDAQAB
-----END PUBLIC KEY-----
以及非对称加密私钥:
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGx9P2d9apGzVnX
SbVTvOe8bATx10+xFS9K6slpJXuPERVVlRSJSh4rWWH59U6gwCizEIS/6KpAPKxQ
dHnZBw9NcS8y/TCnliUIciPvFyQpVTaPGXj3NWZpTGG9RcfUL11uQ4EZG1K31sLt
OS9i1VrhfedeHT4YwFDww00F/LBLAgMBAAECgYEAk4SuOs4oANRFp4vgtjodYDzP
5AAwZKBQqyEaqeTryCvQ7fetP+PD0DBhtc4CNy0UzKp8BS6Hy8p6qx3nZ7mTto3H
aRIG+K+UhD1BOi8ZaxlIV+DBIyEHOnIjwIgKXg0j5bXqI+qLo6zC84O5hlEJPwDR
Wy6tmj8dGXPxY75JUukCQQD3c0YGjdx0Qw6e+zH0g0cYKGmbGiDI1y+5QnZ83Yi2
i3kZUTCLEPIHaiC50u9VD5G6XaPEBv/psLFSbwD84zVHAkEAyGM2hpiVEsu/FTwr
rsONH8O350xTOHmtNHdwRXRgQEvuf5GUMluwxnca/mWb38IVHKQCwGlLxEUZkuXR
A8u+3QJAetjnsulKwQ1pfNQIgPOLoBqwEyhtjkgGkVrFqEfzT2z+uersxp2rCrNN
e/OUjg4ksvk6DF/NPR9TaTFitCm4kQJAeAbtRwun5z1BNF/5LlIVetxJkHKoOmCv
fYi5J/EAIiMZNTIm2U8QgKAg/BYymoFvEduvhj7L0kEtg07CtopYxQJBANW27X9y
DLuxwi6mYJauG1VQ6z4cjDm+TxuuOVcxba4q+VgHufycKyuqsSu6BaqiPeg2+2XF
Td22XO52Jc3EGw8=
-----END PRIVATE KEY-----
搞定之后,提交审核即可。
这些操作完成记得和极光的商务沟通下,不然会被打回
这些操作完成记得和极光的商务沟通下,不然会被打回
这些操作完成记得和极光的商务沟通下,不然会被打回
重要的事情说三遍~
客服小姐姐声音很甜~
极光同样为我们提供了俩种集成方案:
- 本地工程配置
- jcenter 自动集成步骤
2020 年了,必须自动集成搞起来呀~
2.1 配置权限
<!-- Required -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.GET_TASKS" />
<!-- Optional -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
2.2 处理兼容 Android P 默认限制使用 Http 请求
在 res 目录下新建 xml 目录,并新建一个名为 network_security_config.xml 的文件,拷贝如下内容到 xml 里:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
在 AndroidManifest.xml 中配置下:
<application
...
android:networkSecurityConfig="@xml/network_security_config" >
</application>
2.3 检查 project 的 gradle 已支持 jcenter
一般而言,Android Studio 项目默认配置了 Jcenter,但是我们还是要检查一番。
点开工程下 gradle 文件,检查是否配置如下注释俩个地方。
buildscript {
repositories {
google()
jcenter() // 这个
}
// ...
}
allprojects {
repositories {
google()
jcenter() // 还有这个东东
}
}
// ...
2.4 在 module 的 gradle 中配置并添加依赖
android {
// ...
defaultConfig {
// ...
ndk {
//兼容的 cpu 类型
abiFilters 'armeabi'
}
// 极光配置
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "App Key", //Portal上注册的包名对应的 appKey.
JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
]
}
}
dependencies {
// ...
implementation 'cn.jiguang.sdk:jverification:2.5.2'
implementation 'cn.jiguang.sdk:jcore:2.1.4
}
关于依赖最新版本号可直接访问如下链接查看即可:
2.5 添加极光认证混淆配置
-dontoptimize
-dontpreverify
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
-dontwarn com.cmic.**
-keep class com.cmic.** { *; }
-dontwarn com.unicom.**
-keep class com.unicom.** { *; }
-dontwarn cn.com.chinatelecom.**
-keep class cn.com.chinatelecom.** { *; }
2.6 Application 中初始化极光认证
package com.hlq.jiguangdemo.app
import android.app.Application
import android.util.Log
import cn.jiguang.verifysdk.api.JVerificationInterface
import com.hlq.jiguangdemo.BuildConfig
/**
* @author:heliquan
* @date:2020-01-10 00:29
* @desc:
*/
class BaseApplication : Application() {
override fun onCreate() {
super.onCreate()
initJPushSetting()
}
/**
* 初始化极光认证
*/
private fun initJPushSetting() {
JVerificationInterface.init(
this,
5000
) { code, msg ->
val logMsg = when (code) {
8000 -> {
"===> 极光认证初始化成功~! $msg"
}
else -> {
"===> 极光认证初始化失败! $msg"
}
}
Log.e("HLQ_Struggle", logMsg)
}
// 打开调试模式
JVerificationInterface.setDebugMode(BuildConfig.DEBUG)
}
}
别忘记 AndroidManifest 中配置 name 属性。
<application
...
android:name=".app.BaseApplication"
...>
三、实战
Android 6.0 动态申请权限,这个锅刚出来时那是相当痛苦啊,各种忧愁。同样,我这边有个设备是 Android 9.0 系统,那么在基于以上配置完成后,我们首先开始动态申请权限。
3.1 动态申请 READ_PHONE_STATE 权限
关于权限管理库,网上琳琅满目,在此特意推荐一款个人使用较为不错的动态权限管理库:
使用也是很 easy,Follow me~
由于个人习惯使用 Kotlin ,我们先进行 PermissionsDispatcher 基础配置 (app/build) :
// ...
apply plugin: 'kotlin-kapt'
// ...
dependencies {
// ...
// 动态权限申请
implementation "org.permissionsdispatcher:permissionsdispatcher:4.6.0"
kapt "org.permissionsdispatcher:permissionsdispatcher-processor:4.6.0"
}
随后我们在要申请权限的地方新增注解并开始动态请求权限:
package com.hlq.jiguangdemo
import android.Manifest
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import cn.jiguang.verifysdk.api.JVerificationInterface
import permissions.dispatcher.NeedsPermission
import permissions.dispatcher.OnShowRationale
import permissions.dispatcher.RuntimePermissions
// 第一步:新增 RuntimePermissions 注解,标明在编译时生成对应请求映射
@RuntimePermissions
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/**
* 一键登录
*/
public fun oneKeyLogin(view: View) {
// 第四步:检查权限是否授予
// 写这个之前记得 build 下,Runtime 运行时生成
requestReadPhoneStateWithPermissionCheck()
}
private fun handlerOneKeyLogin() {
// 这里开始编写实际的一键登录具体请求代码
}
/**
* 权限请求回调
*/
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
onRequestPermissionsResult(requestCode, grantResults)
}
/**
* 第二步:指明对应要动态申请的权限,可声请多个权限
*/
@NeedsPermission(Manifest.permission.READ_PHONE_STATE)
fun requestReadPhoneState() {
handlerOneKeyLogin()
}
/**
* 第三步:解释说明申请权限具体作用,随后 Build
*/
@OnShowRationale(Manifest.permission.READ_PHONE_STATE)
fun onRequestReadPhoneStateRationale() {
Toast.makeText(this, "请同意 App 请求授权!", Toast.LENGTH_SHORT).show()
}
}
上述代码中,第一步以及第二步必须填写,而为了程序的健壮性,一般我们还会添加例如用户拒绝权限以及用户点击 "不再询问" 的后续操作流程,此处仅仅是为了体验极光的一键登录,暂时完善个动态申请权限即可。😂😂😂
3.2 使用前环境检测
在使用极光一键认证前,我们需要具备如下几个条件:
- 极光一键认证 SDK 是否已初始化完毕;
- 当前的手机网络环境是否可以使用认证(基于流量);
- 是否授予对应权限,获取手机状态等
基于以上三点,我们开始完善 oneKeyLogin 一键登录方法:
/**
* 一键登录
*/
public fun oneKeyLogin(view: View) {
// 检查当前是否初始化成功极光 SDK
if (JVerificationInterface.isInitSuccess()) {
// 判断当前的手机网络环境是否可以使用认证。
if (!JVerificationInterface.checkVerifyEnable(this)) {
Toast.makeText(this, "[2016],msg = 当前网络环境不支持认证", Toast.LENGTH_SHORT).show()
return
}
// 检查权限是否授予
requestReadPhoneStateWithPermissionCheck()
} else {
Toast.makeText(this, "极光 SDK 尚未初始化成功~!", Toast.LENGTH_SHORT).show()
}
}
3.3 一键登录
首先我们查看 API 文档了解关键信息:

这点真心佩服极光开发工程师,几乎都是如果没有则自动获取,很是方便,尤其对于我这样又懒又菜的小白而言。
接口描述也很是贴心,一起来看:

而关于点击授权事件返回码,我们提前了解下,方便后续集成:

为了便于博文演示,还是决定输入一些返回结果,古老的 findViewById 不好玩了,尝尝 Kotlin 神器吧,来先激活一下(app/build):
// 启动 Kotlin Android Extensions
androidExtensions {
experimental = true
}
随后,我们开始完善我们的一键登录细节:
/**
* 处理一键登录细节
*/
private fun handlerOneKeyLogin() {
// 配置 Login Setting
val settings = LoginSettings()
settings.isAutoFinish = true // 登录完成后自动关闭授权页
settings.timeout = 15 * 1000 // 设置超时时间,单位毫秒。 合法范围(0,30000],范围以外默认设置为10000
settings.authPageEventListener = object : AuthPageEventListener() {
override fun onEvent(cmd: Int, msg: String?) {
Log.e(TAG, "===> onEvent code:$cmd msg:$msg")
}
}
// 开始一键登录
JVerificationInterface.loginAuth(
this, settings
) { code, content, operator ->
when (code) {
6000 -> { // Login Token 获取成功
}
else -> {
}
}
tv_login_result.text = "code:$code \n content:$content \n operator:$operator"
}
}
说的再天花烂坠,没个实际效果也是空说,我们 Run 一波,瞅瞅效果如何:

速度很快,有没有感觉到~
3.4 获取手机号
在上述步骤中,我们通过一键登录获取到了 loginToken,而在实际项目中,我们很多时候都需要获取到用户实际的手机号码,那么我们如何根据 loginToken 获取用户手机号呢?
别急,往下看~

这个时候就需要服务端童鞋帮助咯,提供一个接口,通过咱传递的 loginToken 获取对应的手机号码信息咯。
这里不作为重点,这里不具体演示 App 发请求获取手机号咯。

3.5 自定义授权页面 UI 样式
/**
* 自定义授权页面 UI 样式
*/
private fun customUIStyle() {
val qq = ImageView(this)
qq.setImageResource(R.drawable.qq)
val uiConfig = JVerifyUIConfig.Builder()
.setAuthBGImgPath("main_bg")
.setNavColor(-0xff7930)
.setNavText("登录")
.setNavTextColor(-0x1)
.setNavReturnImgPath("umcsdk_return_bg")
.setLogoWidth(70)
.setLogoHeight(70)
.setLogoHidden(false)
.setNumberColor(-0xcccccd)
.setLogBtnText("本机号码一键登录")
.setLogBtnTextColor(-0x1)
.setLogBtnImgPath("umcsdk_login_btn_bg")
.setAppPrivacyOne("应用自定义服务条款一", "https://www.jiguang.cn/about")
.setAppPrivacyTwo("应用自定义服务条款二", "https://www.jiguang.cn/about")
.setAppPrivacyColor(-0x99999a, -0xff7a30)
.setUncheckedImgPath("umcsdk_uncheck_image")
.setCheckedImgPath("umcsdk_check_image")
.setSloganTextColor(-0x666667)
.setLogoOffsetY(50)
.setLogoImgPath("logo_cm")
.setNumFieldOffsetY(170)
.setSloganOffsetY(230)
.setLogBtnOffsetY(254)
.setNumberSize(18)
.setPrivacyState(false)
.setNavTransparent(false)
.addCustomView(
qq, false
) { context, _ ->
Toast.makeText(context, "动态注册的其他按钮222", Toast.LENGTH_SHORT).show()
}
.setPrivacyOffsetY(30).build()
JVerificationInterface.setCustomUIWithConfig(uiConfig)
}
随后在我们刚刚处理一键登录的方法中新增此项:
/**
* 处理一键登录细节
*/
private fun handlerOneKeyLogin() {
customUIStyle()
// ...
}
效果如下,为了演示,效果表介意咯。

有的小伙伴说了,那如果我想要添加自己的一些控件怎么办呢?
很 easy,参考如下截图即可,极光文档写的忒 6 咯,表怪我忒懒了。

3.6 设置授权页弹窗模式
这个更加 easy 了,由于忒晚了,这里就直接演示 low 到爆的效果咯,细节各位慢慢打磨吧~
先来瞅瞅极光小哥哥为我们搞好的文档:

Step 1:在 AndroidManifest 中添加授权页 Activity 并设置对应的 style
<activity
android:name="cn.jiguang.verifysdk.CtLoginActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop"
android:screenOrientation="unspecified"
android:theme="@style/ActivityDialogStyle" />
Step 2:配置具体弹窗 Style
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ActivityDialogStyle">
<!--去掉action bar和标题栏-->
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<!--背景透明-->
<item name="android:windowIsTranslucent">true</item>
<!--dialog圆角-->
<item name="android:windowBackground">@drawable/jverify_dialog_bg</item>
</style>
</resources>
Step 3:定义窗口圆角属性
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp"/>
</shape>
瞅一眼效果:

由于时间原因,暂时草草实现简单效果咯。想想明天的任务,头大。

四、叨叨几句
先说下测试的结果:
网络情况 | 测试结果 |
---|---|
开启 WiFi 关闭流量 | 无法认证 |
开启 WiFi 开启流量 | 一键登录成功 |
开启流量 | 一键登录成功 |
特殊情况测试结果:
SIM 情况 | 测试结果 |
---|---|
有效 SIM 卡 | 一键认证成功 |
无效 SIM 卡 | 无法认证 |
认证速度,纯属个人瞎玩。测试依据,点击登录前记录当前时间戳,并与 SDK 返回时间对比,此处仅供参考。
网络情况 | 测试结果 |
---|---|
300 MB 宽带 WiFi 且开启流量 | 218s |
移动网络 | 98ms |
其实整体流程而言,相对速度,等待期很短暂。
聊下集成上手度吧。
- 上手 easy,文档写的相对来说蛮不错,新手通俗易懂;
- 不足之处 Api 使用和文档有些出入,我遇到情况就是使用官网提供的版本发现有的方法没有,最后自己找的最新版本,这点有点坑。
简单说下极光一键登录流程吧:
当然里面包含很多的细节,比如说如何知晓当前流量归属哪儿个运营商,双卡操作等,这些涉及到我个人知识盲区,暂时不做了解。
整体来说,90 分,很不错。第一次知道极光便是推送,依稀记得简简单单几句话,推送搞定,当时那个兴奋呐,内心默默把极光小哥哥香了一遍。
最后,感谢极光小哥哥,让我再次感受并实实在在体验了一番。
2条评论