美文网首页
Android极光认证配置

Android极光认证配置

作者: 周_0717 | 来源:发表于2020-04-24 14:56 被阅读0次

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

    相关文章

      网友评论

          本文标题:Android极光认证配置

          本文链接:https://www.haomeiwen.com/subject/izppihtx.html