如何实现Android程序化锁屏且支持指纹/面部等非强认证解锁?
问题描述
我正在开发一款启动后即可锁定手机的APP,作为物理锁屏按键的替代方案。已通过以下代码实现功能:
MainActivity.kt
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { LockmeTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Greeting("Android") } } } val deviceManger = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val compName = ComponentName(this, AdminReceiver::class.java) val active: Boolean = deviceManger.isAdminActive(compName) if (!active) { val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN) intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, compName) intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "You should enable the app!") startActivity(intent) }else{ deviceManger.lockNow() } } }
policies.xml
<?xml version="1.0" encoding="utf-8"?> <device-admin> <uses-policies> <force-lock /> </uses-policies> </device-admin>
AndroidManifest.xml
<receiver android:name= ".AdminReceiver" android:description= "@string/app_name" android:label= "@string/app_name" android:exported="false" android:permission= "android.permission.BIND_DEVICE_ADMIN" > <meta-data android:name= "android.app.device_admin" android:resource= "@xml/policies" /> <intent-filter> <action android:name= "android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>
遇到的问题:锁屏后解锁时,系统提示“Device is locked by admin”,要求使用PIN/密码等强认证方式,希望改为使用手机已设置的指纹、面部识别等非强认证方式解锁。
解决方案
问题根源是DevicePolicyManager.lockNow()的默认行为:设备管理员调用该方法时,系统会强制触发强认证要求,绕过生物识别。以下是两种可行解决思路:
1. 替代lockNow(),使用系统常规锁屏触发方式
放弃依赖设备管理员的force-lock权限,直接发送系统锁屏广播,效果与按物理锁屏键一致,解锁时允许使用生物识别:
// 替换原有的deviceManger.lockNow()代码 val intent = Intent(Intent.ACTION_SCREEN_OFF) sendBroadcast(intent)
需在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Android 10及以上版本,WRITE_SETTINGS权限需用户手动授权,可通过以下代码引导开启:
if (!Settings.System.canWrite(this)) { val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) intent.data = Uri.parse("package:" + packageName) startActivity(intent) }
2. 保留设备管理员权限(Android 11+)
Android 11(API 30)及以上版本,DevicePolicyManager提供带参数的lockNow(int flags)方法,传入LOCK_FLAG_ALLOW_BIOMETRICS_AFTER_LOCK标志可允许生物识别解锁:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { deviceManger.lockNow(DevicePolicyManager.LOCK_FLAG_ALLOW_BIOMETRICS_AFTER_LOCK) } else { // 低版本 fallback 到第一种方案 val intent = Intent(Intent.ACTION_SCREEN_OFF) sendBroadcast(intent) }
注意:仅保留force-lock这一项设备管理员政策,避免触发额外安全限制。
注意事项
- 第一种方案兼容性更强,适用于大多数Android版本,且无需设备管理员权限,彻底规避强认证强制要求。
- 部分定制ROM可能限制
ACTION_SCREEN_OFF广播,需覆盖主流机型测试。
内容的提问来源于stack exchange,提问作者Mervin Hemaraju
相关产品推荐
相关产品推荐

