極光一鍵登錄集成手冊 | Android

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

前言

某天翻閱極光文檔時,發現極光也推出了一鍵登錄,先來看個效果圖:

之前有幸體驗了 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 且開啓流量 218ms
移動網絡 98ms

其實整體流程而言,相對速度,等待期很短暫。

聊下集成上手度吧。

  • 上手 easy,文檔寫的相對來說蠻不錯,新手通俗易懂;
  • 不足之處 Api 使用和文檔有些出入,我遇到情況就是使用官網提供的版本發現有的方法沒有,最後自己找的最新版本,這點有點坑。

簡單說下極光一鍵登錄流程吧:

用戶極光認證 SDK運營商我要喝奶(一鍵登錄)稍等,我先看看你屬於哪兒家的娃(找歸屬運營商,前提開啓流量)你娃要喝奶,給我授權(獲取預取號)是我家娃,給你授權你餵奶吧(返回預取號)你娃喝啥牌子的奶啊?(請求一鍵登錄)我娃只喝某某牌奶粉(拿到一鍵登錄返回結果)給你奶(拿到一鍵登錄 token 信息)謝謝,真好用戶極光認證 SDK運營商

當然裏面包含很多的細節,比如說如何知曉當前流量歸屬哪兒個運營商,雙卡操作等,這些涉及到我個人知識盲區,暫時不做了解。

整體來說,90 分,很不錯。第一次知道極光便是推送,依稀記得簡簡單單幾句話,推送搞定,當時那個興奮吶,內心默默把極光小哥哥香了一遍。

最後,感謝極光小哥哥,讓我再次感受並實實在在體驗了一番。

參考資料

  1. 極光認證 Android 集成指南
  2. 極光 GitHub
  3. PermissionsDispatcher
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章