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

Android锁屏错误密码监听遇设备管理员权限报错,求修复方案

问题描述

开发一款安全应用,需求是用户输入锁屏错误密码时发送通知。搜索相关方案时找到的链接均失效,参考commonsguy的DeviceAdmin示例项目实现后,应用无法正常运行,持续抛出安全错误:No active admin owned by uid 10418 for policy #0。

相关代码如下:

MainActivity代码

ComponentName cn=new ComponentName(this, AdminReceiver.class);
DevicePolicyManager mgr=
        (DevicePolicyManager)getSystemService(DEVICE_POLICY_SERVICE);

if (mgr.isAdminActive(cn)) {
    int msgId;

    if (mgr.isActivePasswordSufficient()) {
        msgId=R.string.compliant;
    }
    else {
        msgId= R.string.not_compliant;
    }

    Toast.makeText(this, msgId, Toast.LENGTH_LONG).show();
}
else {
    Intent intent=
            new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, cn);
    intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
            getString(R.string.device_admin_explanation));
    startActivity(intent);
}

finish();

AdminReceiver类代码

public class AdminReceiver extends DeviceAdminReceiver {
    @Override
    public void onEnabled(Context ctxt, Intent intent) {
        ComponentName cn = new ComponentName(ctxt, AdminReceiver.class);
        DevicePolicyManager mgr =
                (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);

        mgr.setPasswordQuality(cn,
                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);

        onPasswordChanged(ctxt, intent);
    }

    @Override
    public void onPasswordChanged(Context ctxt, Intent intent) {
        DevicePolicyManager mgr =
                (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);
        int msgId;

        if (mgr.isActivePasswordSufficient()) {
            msgId = R.string.compliant;
        } else {
            msgId = R.string.not_compliant;
        }

        Toast.makeText(ctxt, msgId, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onPasswordFailed(Context ctxt, Intent intent) {
        Toast.makeText(ctxt, R.string.password_failed, Toast.LENGTH_LONG)
                .show();
    }

    @Override
    public void onPasswordSucceeded(Context ctxt, Intent intent) {
        Toast.makeText(ctxt, R.string.password_success, Toast.LENGTH_LONG)
                .show();

    }
}

XML配置文件(res/xml/device_admin.xml)

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-policies>
        <limit-password/>

        <watch-login/>
    </uses-policies>

</device-admin>

请问该如何修复这个问题?


修复方案

这个错误的核心原因是调用DevicePolicyManager的API时,传入的ComponentName对应的设备管理员未被激活,或者权限验证不通过,可从以下几个方面排查修复:

1. 确认AdminReceiver在AndroidManifest中正确注册

必须在Manifest中给AdminReceiver添加android.app.action.DEVICE_ADMIN_ENABLED的intent-filter,并且关联device-admin的xml配置,示例如下:

<receiver
    android:name=".AdminReceiver"
    android:description="@string/app_name"
    android:label="@string/app_name"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

注意:android:permission="android.permission.BIND_DEVICE_ADMIN"是必填项,缺失会导致管理员无法被系统识别激活。

2. 避免直接调用onPasswordChanged方法

在onEnabled中直接调用onPasswordChanged(ctxt, intent)是错误的,此时传入的Intent并非密码变更触发的合法Intent,会导致DevicePolicyManager权限验证异常。正确做法是提取公共密码检查逻辑:

@Override
public void onEnabled(Context ctxt, Intent intent) {
    ComponentName cn = new ComponentName(ctxt, AdminReceiver.class);
    DevicePolicyManager mgr =
            (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);

    mgr.setPasswordQuality(cn, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
    // 调用公共检查方法,而非直接触发onPasswordChanged
    checkPasswordCompliance(ctxt);
}

// 提取公共密码检查逻辑
private void checkPasswordCompliance(Context ctxt) {
    DevicePolicyManager mgr =
            (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);
    int msgId = mgr.isActivePasswordSufficient() ? R.string.compliant : R.string.not_compliant;
    Toast.makeText(ctxt, msgId, Toast.LENGTH_LONG).show();
}

@Override
public void onPasswordChanged(Context ctxt, Intent intent) {
    checkPasswordCompliance(ctxt);
}

3. 验证设备管理员激活结果

启动添加管理员的Intent后,需在onActivityResult中确认激活状态,避免在未激活时执行需要管理员权限的操作:
修改MainActivity代码,替换startActivity为startActivityForResult并添加结果回调:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ComponentName cn=new ComponentName(this, AdminReceiver.class);
    DevicePolicyManager mgr=
            (DevicePolicyManager)getSystemService(DEVICE_POLICY_SERVICE);

    if (mgr.isAdminActive(cn)) {
        int msgId = mgr.isActivePasswordSufficient() ? R.string.compliant : R.string.not_compliant;
        Toast.makeText(this, msgId, Toast.LENGTH_LONG).show();
        finish();
    }
    else {
        Intent intent=
                new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, cn);
        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                getString(R.string.device_admin_explanation));
        startActivityForResult(intent, 1001);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1001) {
        if (resultCode == RESULT_OK) {
            Toast.makeText(this, R.string.admin_enabled, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, R.string.admin_not_enabled, Toast.LENGTH_LONG).show();
        }
        finish();
    }
}

4. 适配Android版本权限

Android 10及以上对设备管理员权限验证更严格,需在Manifest中声明必要权限:

<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />

注:该权限为系统权限,普通应用无法直接获取,仅用于声明用途。


内容的提问来源于stack exchange,提问作者Berkay Isıkoglu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:05:39