背景
需要实现开机PIN密码自动填充的功能,由于PIN输入控件是一个自定义View com.android.keyguard.PasswordTextView extends View
。在使用辅助功能AccessibilityService
时,无法通过类似EditText
一样直接,将密码填充进去。只能通过模拟按键点击。然后默认下按钮点击输入时密码数字有一瞬间是明文显示的,存在泄漏的风险。
探索
为什么要采用 AccessibilityService
PIN 密码的输入为什么非得采用复杂的AccessibilityService来实现呢?
由于PIN涉及到操作系统与SIM卡的通信,在官方设计中属于极度危险的操作,在应用层由于权限的问题,被各种拦截掉了。
即,纯代码层面的实现,包括反射等路子都被禁掉了。
java.lang.SecurityException: Neither user 10141 nor current process has android.permission.MODIFY_PHONE_STATE.
这就是结果。此路不通。
故,要么让你的应用成为系统应用获取到相应的权限,要么放弃吧。
确定采用 AccessibilityService,密码如何防止泄露?
其实很简单,只是认知的问题。在密码输入时,那个瞬间的明文展示,其实是一个可设置的功能。即我们可以同设置项去关闭。
小米系统路径:
设置 -> 系统安全 -> 显示密码 -> 选择开关即可
当选择关闭之后,再输入密码时,就没有那个瞬间明文显示的问题了。
那么问题来了,如何代码控制呢?
代码控制是否显示密码
大多数系统设置项,都可以通过代码来操作。
show you the code !!!
/**
* 1:ON;0:OFF
*/
fun Context.setModeTextShowPassword(mode: Int) {
try {
Settings.System.putInt(contentResolver, Settings.System.TEXT_SHOW_PASSWORD, mode)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 1:ON;0:OFF
*/
fun Context.getModeTextShowPassword(): Int {
return Settings.System.getInt(contentResolver, Settings.System.TEXT_SHOW_PASSWORD, 0)
}
如上代码,即可控制是否显示密码。