Android 高仿支付宝手势密码

    支付宝的手势密码 支持两种方式,第一种是进入app 时启动,第二种是进入财富时启动。

  1,我们先来分析下第一种方式,进入APP 时启动手势密码:

   进入app 时启动手势密码,有一个关键的知识点,前后台切换,如何判断app 应用做了前后台切换了呢?

 (1)使用lifecycle 组件 :

ProcessLifecycleOwner

该类提供了整个 app 进程的 lifecycle。

可以将其视为所有 activity 的 LifecycleOwner ,其中 Lifecycle.Event.ON_START 代表app 进入前台,而 Lifecycle.Event.ON_STOP 代表app 进入后台。当然(Lifecycle.Event.On_RESUME 和 Lifecycle.Event.ON_PAUSE 也可以分别代表进入前台和后台)。

代码示例:

 ProcessLifecycleOwner.get().lifecycle.addObserver(object:LifecycleObserver{

            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun onForeground(){
                EasyLog.e(TAG,"== onForeground==")
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun onBackground(){
                EasyLog.e(TAG,"== onBackground==")
            }


        });

ProcessLifecycle 能很好的监听前后台切换,但是 不太适合做手势密码的前后台切换,首先首页和登录页是不需要弹出手势密码的,这些页面要过滤,ProcessLifecycle 不好做到这一点。下面看第二种方法。

(2)使用 lifecycleCallbacks接口:

Application.ActivityLifecycleCallbacks

 通过这个接口,我们对onActivityStart回调方法里记录启动的次数 mActivityCount++,onActivityStop 回调里对 mActivityCount-- ,当mActivityCount == 1 时认为在前台,mActivityCount ==0 在后台。代码如下:



/**
 * 监听 前后台启动
 * 自定义 可以很容易过滤一些不需要跳出手势密码的特殊的场景,比如 登录页
 */
class GestureLifecycleHandler constructor(context:Context): Application.ActivityLifecycleCallbacks {


    companion object{
        private const val TAG = "GestureLifecycleHandler"
    }

    private val uiScope  =  CoroutineScope(Dispatchers.Main)

    private var isOpenHandLock = false
    init {


    }
    
    /**
     * 记录 activity 前后台情况
     */
    private var mActivityCount: Int = 0

    override fun onActivityPaused(activity: Activity?) {

    }

    override fun onActivityResumed(activity: Activity?) {



    }

    override fun onActivityStarted(activity: Activity?) {
        if(activityFilter(activity)){
            return
        }

        mActivityCount ++
        EasyLog.e(TAG,"onForeground = $mActivityCount")
        uiScope.launch {
            withContext(Dispatchers.IO){
                isOpenHandLock =  GestureManager.getAppGestureState()
                if(isOpenHandLock && mActivityCount == 1){
                   GestureActivity.actionStart(activity!!,GestureActivity.GestureState.Verify)
                }
            }

        }

    }

    override fun onActivityDestroyed(activity: Activity?) {

    }

    override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {

    }

    override fun onActivityStopped(activity: Activity?) {
        if(activityFilter(activity)){
            return
        }
        mActivityCount--
        EasyLog.e(TAG,"onBackground = $mActivityCount")

    }

    override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {

    }

    private fun activityFilter(activity: Activity?):Boolean{
        return activity is SplashActivity
    }
}

效果图如下:

2,我们分析第二种方式,进入财富时弹出手势密码

 财富模块是个fragment ,也就是说要对财富fragment 监听前后台的变化,这个时候可以使用ProcessLifecycleOwner 对Fragment监听,代码如下:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ProcessLifecycleOwner.get().lifecycle.addObserver(GestureLife(this))
    }
private const val TAG = "GestureLife"

 open class GestureLife(val fragment: GestureLockFragment) :LifecycleObserver{


     private val uiScope  =  CoroutineScope(Dispatchers.Main)


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onVisible() {
       EasyLog.e(TAG,"==ON_RESUME==")
        if(fragment.isHidden){
            EasyLog.e(TAG,"等待台跳出手势密码")
            fragment.waitingGesture = true

        }
        if(!fragment.isHidden||fragment.isVisible){
            EasyLog.e(TAG,"==isVisible==")
            uiScope.launch {
                withContext(Dispatchers.IO){
                    val  isOpenHandLock =  GestureManager.getFragmentGestureState()
                    if(isOpenHandLock  && !GestureLockFragment.showGesture){
                          GestureLockFragment.showGesture = true
                          GestureActivity.actionStart(ActivityUtils.getTopActivity(),GestureActivity.GestureState.Verify)
                    }
                }

            }
        }


    }
     @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
     fun onBackground(){
         EasyLog.e(TAG,"==onBackground==")
         GestureLockFragment.showGesture = false
     }

}

这里要处理两种情况,第一种财富这个fragment 前后台切换后,fragment 是可见的,那么久直接弹出手势,如果不可见要等待可见的时再次弹出,所以还要处理onHidden,

 override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        EasyLog.e(TAG,"onHiddenChanged")
        if(!hidden){
            if(waitingGesture && !showGesture){
                waitingGesture = false
                showGesture = true
                GestureActivity.actionStart(activity!!, GestureActivity.GestureState.Verify)
            }
        }
    }

        效果如下图:

源码:

https://github.com/ThirdPrince/GestureDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值