ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Android定制超级密码清除 Password 锁屏时跳过 IME 动画流程

Android定制超级密码清除 Password 锁屏时跳过 IME 动画流程 文章目录Android定制超级密码清除 Password 锁屏时跳过 IME 动画流程一、问题背景二、关键文件索引三、设置方KeyguardSecurityContainer.processInputSuperPwd3.1 完整上下文3.2 执行时序四、消费方KeyguardPasswordView.startDisappearAnimation4.1 完整代码4.2 跳过动画的 5 个步骤五、正常流程 vs 快速通道对比六、完整时序图七、为什么只在 Password 类型设置此标志Android定制超级密码清除 Password 锁屏时跳过 IME 动画流程适用代码路径wrelease/frameworks/base/packages/SystemUI平台RK3576 AN16 EDLA IFPD一、问题背景当通过超级密码清除 Password 类型锁屏时会调用mKeyguardSecurityCallback.dismiss()触发锁屏界面消失。KeyguardPasswordView的正常消失动画依赖与 IME输入法键盘的复杂联动动画controlWindowInsetsAnimation。但在超级密码清除场景下Password 输入框此时可能已经失去焦点、IME 键盘状态异常导致原生动画流程卡死或无法完成锁屏无法正常消失。解决方案在触发 Password 类型清除时通过SystemProperties设置一个标志位sys.stb.password.super true让KeyguardPasswordView.startDisappearAnimation()跳过复杂的 IME 动画直接执行清理逻辑。二、关键文件索引文件路径作用KeyguardSecurityContainer.javasrc/com/android/keyguard/标志位设置方processInputSuperPwd中 Password 分支设置sys.stb.password.super trueKeyguardPasswordView.javasrc/com/android/keyguard/标志位消费方startDisappearAnimation中检测并跳过 IME 动画执行后重置为false三、设置方KeyguardSecurityContainer.processInputSuperPwdKeyguardSecurityContainer.java#L1021-10273.1 完整上下文// 第 994-1051 行}elseif(dialogModeINPUT_SUPER_PASSWORD){savedCredentialLockscreenCredential.createNone();pwdValueSystemProperties.get(KEY,);// KEY persist.sys.screen.lockif(inputEditText.getText().toString().trim().equals(oldPassword)){// ★ 超级密码验证通过mKeyguardSecurityCallback.reportUnlockAttempt(userId,true,0);// 根据当前锁类型解析备份凭据switch(securityMode){casePattern:// ... 图案解析 ...break;casePIN:// ... PIN 解析 ...break;casePassword:android.util.Log.d(TAG,securityMode ---- Password);pwdValueSystemProperties.get(KEY,);mKeyguardSecurityCallback.dismiss(true,userId,SecurityMode.Password);// ↑ 调用 dismiss 触发锁屏消失 → KeyguardPasswordView.startDisappearAnimation()savedCredentialLockscreenCredential.createPassword(pwdValue.substring(3));SystemProperties.set(sys.stb.password.super,true);// ★★★ 设置标志位通知 KeyguardPasswordView 跳过 IME 动画break;default:break;}// 子线程验证凭据newThread(()-{try{lockPatternUtils.checkCredential(savedCredential,userId,null);}catch(RequestThrottledExceptione){e.printStackTrace();}}).start();// 清除锁屏lockPatternUtils.setLockCredential(LockscreenCredential.createNone(),savedCredential,userId);lockPatternUtils.setLockScreenDisabled(true,userId);// 清理弹窗与通知mAlertDialog.dismiss();settingsData.screenLock.setSwitch(false);IntentintentnewIntent();intent.setPackage(com.android.settings);intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);intent.setAction(action.screen_lock.state.cancel);getContext().sendBroadcast(intent);}}3.2 执行时序超级密码验证通过 │ ├─ mKeyguardSecurityCallback.dismiss(true, userId, SecurityMode.Password) │ │ │ └──→ KeyguardPasswordView.startDisappearAnimation(finishRunnable) 被调用 │ │ │ └──→ 检测 sys.stb.password.super true → 跳过 IME 动画 │ ├─ SystemProperties.set(sys.stb.password.super, true) ← 设置标志位 │ ├─ setLockCredential(None, savedCredential, userId) → 底层清除锁 ├─ setLockScreenDisabled(true, userId) └─ dismiss 弹窗 发送广播dismiss()调用发生在set(sys.stb.password.super, true)之前第 1024 行在 1026 行之前但dismiss触发的是异步动画流程startDisappearAnimation实际执行时标志位已经设置完成。四、消费方KeyguardPasswordView.startDisappearAnimationKeyguardPasswordView.java#L232-2544.1 完整代码OverridepublicbooleanstartDisappearAnimation(RunnablefinishRunnable){// Add by stb: Teachmint_W93B-DH_3576_AN16_EDLA-53// 超级密码解锁Password时跳过复杂的IME动画直接执行收尾逻辑if(!SystemProperties.getBoolean(persist.sys.stb.edla_test,false)){Log.d(stb,startDisappearAnimation: );if(SystemProperties.getBoolean(sys.stb.password.super,false)){// ★ 检测到超级密码清除 Password 锁的标志位// 步骤1同步清除输入框焦点if(mPasswordEntry!null){Log.d(stb,mPasswordEntry ! null: );mPasswordEntry.clearFocus();mPasswordEntry.getWindowInsetsController().hide(WindowInsets.Type.ime());}// 步骤2同步隐藏键盘InputMethodManagerimm(InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);if(imm!null){Log.d(stb,imm ! null);imm.hideSoftInputFromWindow(getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY);imm.hideSoftInputFromWindow(getWindowToken(),0);}// 步骤3执行 IME 动画收尾runOnFinishImeAnimationRunnable();// 步骤4执行外部传入的完成回调finishRunnable.run();// 步骤5重置标志位SystemProperties.set(sys.stb.password.super,false);returntrue;// ★ 提前返回跳过正常 IME 动画流程}}// ↓↓↓ 正常流程超级密码场景下不会执行到此处↓↓↓getWindowInsetsController().controlWindowInsetsAnimation(ime(),100,Interpolators.LINEAR,null,newWindowInsetsAnimationControlListener(){OverridepublicvoidonReady(NonNullWindowInsetsAnimationControllercontroller,inttypes){ValueAnimatoranimValueAnimator.ofFloat(1f,0f);anim.addUpdateListener(animation-{if(controller.isCancelled()){return;}floatvalue(float)animation.getAnimatedValue();floatfractionanim.getAnimatedFraction();InsetsshownInsetscontroller.getShownStateInsets();intdist(int)(-shownInsets.bottom/4*fraction);InsetsinsetsInsets.add(shownInsets,Insets.of(0,0,0,dist));if(mDisappearAnimationListener!null){mDisappearAnimationListener.setTranslationY(-dist);}controller.setInsetsAndAlpha(insets,value,fraction);setAlpha(value);});anim.addListener(newAnimatorListenerAdapter(){OverridepublicvoidonAnimationEnd(Animatoranimation){DejankUtils.postAfterTraversal(()-{controller.finish(false);runOnFinishImeAnimationRunnable();finishRunnable.run();mDisappearAnimationListenernull;});}});anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);anim.start();}OverridepublicvoidonFinished(NonNullWindowInsetsAnimationControllercontroller){}OverridepublicvoidonCancelled(NonNullWindowInsetsAnimationControllercontroller){}});returnfalse;}4.2 跳过动画的 5 个步骤startDisappearAnimation(finishRunnable) │ ├─ 检查 persist.sys.stb.edla_test false ← 非测试模式才执行 │ └─ 是 → 继续 │ ├─ 检查 sys.stb.password.super true │ └─ 是 → 进入快速通道 │ │ ┌─────────────────────────────────────────────────────┐ │ │ 步骤1mPasswordEntry.clearFocus() │ │ │ 清除输入框焦点 │ │ │ 隐藏 IME 窗口插入 │ │ ├─────────────────────────────────────────────────────┤ │ │ 步骤2imm.hideSoftInputFromWindow() × 2 │ │ │ 强制隐藏键盘HIDE_IMPLICIT_ONLY 无flag │ │ ├─────────────────────────────────────────────────────┤ │ │ 步骤3runOnFinishImeAnimationRunnable() │ │ │ 执行 IME 动画收尾回调 │ │ ├─────────────────────────────────────────────────────┤ │ │ 步骤4finishRunnable.run() │ │ │ 执行外部传入的完成回调锁屏消失后续逻辑 │ │ ├─────────────────────────────────────────────────────┤ │ │ 步骤5SystemProperties.set(..., false) │ │ │ 重置标志位不影响后续正常流程 │ │ └─────────────────────────────────────────────────────┘ │ └─ 否 → 正常 IME 联动动画流程 controlWindowInsetsAnimation(ime(), ...) ├ ValueAnimator 从 1f → 0f 渐隐 ├ 与 IME 键盘位置联动 └ 动画结束后 controller.finish() finishRunnable.run()五、正常流程 vs 快速通道对比对比项正常密码解锁超级密码清除 Password 锁触发条件用户输入正确密码超级密码验证通过 securityMode Password标志位sys.stb.password.super不存在或为falsesys.stb.password.super true输入框状态用户正在输入输入框活跃密码输入框可能已失去焦点IME 键盘状态键盘已弹出可联动动画键盘可能已消失或状态异常消失方式controlWindowInsetsAnimationValueAnimator渐隐动画直接clearFocus()hideSoftInput()finishRunnable.run()动画时长~300ms与 IME 协调即时同步执行标志位重置不需要执行后重置为false六、完整时序图KeyguardSecurityContainer KeyguardPasswordView ──────────────────────────────────────────────────────────────────────── processInputSuperPwd() │ ├─ 超级密码验证通过 │ ├─ mKeyguardSecurityCallback │ .dismiss(true, userId, Password) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ └──────→│ startDisappearAnimation(finishRunnable) │ │ │ │ │ │ check: persist.sys.stb.edla_test false ? │ │ │ → 是 │ │ │ │ ├─ SystemProperties.set( │ check: sys.stb.password.super true ? │ │ sys.stb.password.super, │ → 是刚设置 │ │ true) │ │ │ │ mPasswordEntry.clearFocus() │ ├─ setLockCredential(None, │ mPasswordEntry.hide(ime) │ │ savedCredential, userId) │ │ │ │ imm.hideSoftInputFromWindow() × 2 │ ├─ setLockScreenDisabled(true) │ │ │ │ runOnFinishImeAnimationRunnable() │ ├─ mAlertDialog.dismiss() │ │ │ │ finishRunnable.run() │ ├─ screenLock.setSwitch(false) │ │ │ │ SystemProperties.set( │ ├─ sendBroadcast(action │ sys.stb.password.super, │ │ .screen_lock.state.cancel) │ false) ← 重置标志位 │ │ │ │ ▼ │ return true ← 跳过正常 IME 动画 │ └────────────────────────────────────────────┘七、为什么只在 Password 类型设置此标志锁类型输入界面startDisappearAnimation实现是否需要此标志PINKeyguardPINView无复写此方法使用父类默认实现不需要PatternKeyguardPatternView无复写此方法不需要PasswordKeyguardPasswordView复写了此方法使用controlWindowInsetsAnimation与 IME 联动需要只有KeyguardPasswordView重写了startDisappearAnimation并使用了 IME 联动动画所以只有 Password 类型需要这个标志位来跳过异常路径。如果对你有帮助就一键三连呗关注点赞收藏我会持续更新更多干货~~
返回列表