注册
环信即时通讯云

环信即时通讯云

单聊、群聊、聊天室...
环信开发文档

环信开发文档

Demo体验

Demo体验

场景Demo,开箱即用
RTE开发者社区

RTE开发者社区

汇聚音视频领域技术干货,分享行业资讯
技术讨论区

技术讨论区

技术交流、答疑
资源下载

资源下载

收集了海量宝藏开发资源
iOS Library

iOS Library

不需要辛辛苦苦的去找轮子, 这里都有
Android Library

Android Library

不需要辛辛苦苦的去找轮子, 这里都有

Android 高仿支付宝手势密码

前言支付宝的手势密码 支持两种方式,第一种是进入app 时启动,第二种是进入理财时启动。实现1,我们先来分析下第一种方式,进入APP 时启动手势密码进入app 时启动手势密码,有一个关键的知识点,前后台切换,如何判断app 应用做了前后台切换了呢?(1) 使用...
继续阅读 »

前言

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

实现

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

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

(1) 使用ProcessLifecycleOmner

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接口:

通过这个接口,我们对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
}
}

202109030924010.gif

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)
}
}
}

20210903094115133.gif

收起阅读 »