Android极光认证配置

2020-04-24  本文已影响0人  周_0717

更新日期: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

上一篇下一篇

猜你喜欢

热点阅读