You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 09:21:35