Android极光认证配置

更新日期:2020.07.02
依赖版本:
'cn.jiguang.sdk:jcore:2.3.4'
'cn.jiguang.sdk:jverification:2.6.2'
新版本对认证activity内容进行了包装,导致原本对反射调用失效,新的实现如下:

@SuppressLint("ResourceType")
override fun onActivityStarted(activity: Activity) {
    if (activity::class.java == CtLoginActivity::class.java) {
        val phoneNumber = activity.intent.getStringExtra("mobile")
        val operatorType = activity.intent.getStringExtra("operator")
        if (TextUtils.isEmpty(phoneNumber)) {
            activity.onBackPressed()
        } else {
            val jsonObject = JSONObject()
            jsonObject.putOpt("mobile", phoneNumber)
            jsonObject.putOpt("operator", operatorType)
            EventManagerImpl.get().post(null, SimpleEvent(AppConstant.EVENT_JPUSH_VERIFY, jsonObject))
            try {
                val realFiled = BaseActivity::class.java.getDeclaredField("ctLoginActivity")
                realFiled.isAccessible = true
                val realValue = realFiled.get(activity)
                val p = cn.jiguang.verifysdk.activity.a::class.java.getDeclaredMethod("onClick", View::class.java)
                val view = View(AppContext.get())
                view.id = 1007
                p.invoke(realValue, view)
            } catch (e: Exception) {
                LogUtil.e(e.toString())
                activity.onBackPressed()
            }
        }
    } else if (activity::class.java == LoginAuthActivity::class.java) {
        val phoneNumber = activity.intent.getStringExtra("securityphone")
        val type = activity.intent.getStringExtra("operatorType")
        val operatorType = when (type) {
            "1" -> {
                "CM"
            }
            "3" -> {
                "CT"
            }
            else -> {
                "CU"
            }
        }
        if (TextUtils.isEmpty(phoneNumber)) {
            JVerificationInterface.dismissLoginAuthActivity()
        } else {
            val jsonObject = JSONObject()
            jsonObject.putOpt("mobile", phoneNumber)
            jsonObject.putOpt("operator", operatorType)
            EventManagerImpl.get().post(null, SimpleEvent(AppConstant.EVENT_JPUSH_VERIFY, jsonObject))
            try {
                val realFiled = BaseActivity::class.java.getDeclaredField("ctLoginActivity")
                realFiled.isAccessible = true
                val realValue = realFiled.get(activity)
                val p = cn.jiguang.verifysdk.l.a::class.java.getDeclaredMethod("p")
                p.isAccessible = true
                p.invoke(realValue)
            } catch (e: Exception) {
                LogUtil.e(e.toString())
                JVerificationInterface.dismissLoginAuthActivity()
            }
        }
    }
}

依赖版本:
'cn.jiguang.sdk:jcore:2.3.0'
'cn.jiguang.sdk:jverification:2.5.5'

基本流程:

  1. SDK初始化:api-->JPushInterface.init;注意一定必须要在主线程初始化,否则即使初始化成功,也会导致后面到步骤出错;报错是因为只有3大运营商的认证SDK初始化全部成功,极光认证的相关功能才可以使用,极光官方给出到说法是会在2.6.0版本修复。
  2. 提前获取预登录信息:api-->JPushInterface.preLogin;提前调用可以减少获取认证token的时间,这一步可以省略;调用时机可以在退出登录时,启动后发现未登录的时候,或者在打开登录页面时候(这个时候略微有点晚,可能会卡住页面)。
  3. 获取一键登录token:api-->JVerificationInterface.loginAuth;这个api会唤起极光的认证页面CtLoginActivity(电信和联通的认证页面)和LoginAuthActivity(移动的认证页面),所以首先需要在AndroidManifest中注册这两个activity;这两个activity中包含的主要信息有脱敏后手机号,对应运营协议,以及认证按钮等。由于获取认证token的api没有公开,默认只支持通过点击认证页面上的认证按钮,然后在loginAuth的回调中获取。虽然认证页面Activity的样式可以通过AndroidManifest设置style或者在api中配置对应setting来改变,但页面内容显示只能通过api的配置参数来调整,所以当公司设计的UI与极光默认UI相差较多时,改起来非常痛苦。
    绕过极光认证页面实现完全自定义视图但方法如下:
    1)设置activity生命监听registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback),在onActivityStarted回调中对CtLoginActivity和LoginAuthActivity进行处理;(之所以不在onActivityCreated方法处理,是因为有几次未能拿到Intent内对数据)
    2)如果监听到CtLoginActivity,从intent内拿取基本信息:手机号(加密过的,中间4位*),运营商类型( "CU" :联通,"CT":电信,"CM" :移动);通过反射获取onClick方法,然后模拟点击页面上的认证按钮,调用SDK内部的获取认证token的方法,结果将在在loginAuth方法回调中返回。
val phoneNumber = activity.intent.getStringExtra("mobile")
val operatorType = activity.intent.getStringExtra("operator")
if (TextUtils.isEmpty(phoneNumber)) {
    activity.onBackPressed()
} else {
    //将基本信息传递到页面上
    val jsonObject = JSONObject()
    jsonObject.putOpt("mobile", phoneNumber)
    jsonObject.putOpt("operator", operatorType)
    EventManagerImpl.get().post(null, SimpleEvent(AppConstant.EVENT_JPUSH_VERIFY, jsonObject))
    try {
        //模拟认证按钮点击
        val p = activity.javaClass.getDeclaredMethod("onClick", View::class.java)
        val view = View(AppContext.get())
        view.id = 1007
        p.invoke(activity, view)
    } catch (e: Exception) {
        activity.onBackPressed()
    }
}

3)如果监听到LoginAuthActivity,从intent内拿取基本信息:手机号(加密过的,中间4位*),运营商类型( "3":电信,"1" :移动,其他:联通);通过反射获取类中的p方法,调用SDK内部的获取认证token的方法,结果将在在loginAuth方法回调中返回。

val phoneNumber = activity.intent.getStringExtra("securityphone")
val type = activity.intent.getStringExtra("operatorType")
//统一运营商标识
val operatorType = when (type) {
    "1" -> {
        "CM"
    }
    "3" -> {
        "CT"
    }
    else -> {
        "CU"
    }
}
if (TextUtils.isEmpty(phoneNumber)) {
    JVerificationInterface.dismissLoginAuthActivity()
} else {
    //将基本信息传递到页面上
    val jsonObject = JSONObject()
    jsonObject.putOpt("mobile", phoneNumber)
    jsonObject.putOpt("operator", operatorType)
    EventManagerImpl.get().post(null, SimpleEvent(AppConstant.EVENT_JPUSH_VERIFY, jsonObject))
    try {
        //反射调用认证方法
        val p = activity.javaClass.getDeclaredMethod("p")
        p.isAccessible = true
        p.invoke(activity)
    } catch (e: Exception) {
        JVerificationInterface.dismissLoginAuthActivity()
    }
}

4)调用loginAuth方法,设置弹出极光认证页面不可见(我是将页面模式设置为弹窗模式,长宽均为0),通过VerifyListener监听方法结果(由认证页面返回);方法成功后会创建2)或3)中的Activity,经过上面几步的处理,可以拿到基本信息(手机号,运营商),认证token(返回到VerifyListener内),然后关闭了极光的认证页面。
另外,使用运营商认证必须要在页面上显示对应运营商的协议:

{
  "运营商": "联通",
  "协议名称": "《联通统一认证服务条款》",
  "协议地址": "https://opencloud.wostore.cn/authz/resource/html/disclaimer.html?fromsdk=true"
}, {
  "运营商": "电信"
  "协议名称": "《天翼账号服务与隐私协议》"
  "协议地址": "https://ctaccount.21cn.com/agreementList.html?hidetop=true"
}, {
  "运营商": "移动",
  "协议名称": "《中国移动认证服务条款》"
  "协议地址": "https://wap.cmpassport.com/resources/html/contract.html"
}
  1. 现在应该已经拿到了页面需要的全部信息,可以自定义绘图了。
  1. 将第3步获取的token传递到后台验证;需要注意token是有有效时间的,如果token失效,可重复第3步,重新获取token。

2020-04-21

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容