如何避免此异常
E/AndroidRuntime(26113): Caused by: java.lang.SecurityException: No active admin owned by uid XXXX for policy #3
调用此时:
public static void lockScreen(Context context) {
Log.d(TAG, "lockScreen");
ComponentName mDeviceAdminSample = null;
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
dpm.lockNow();
}
我遇到了与OP相同的错误。由于只有其他答案的组合对我有帮助,以下是我使 OP 代码示例正常工作的演练:
- 确保已创建设备管理接收器和 xml 策略文件,如 https://developer.android.com/guide/topics/admin/device-admin.html 中所述
- 将具有 xml 策略文件引用的管理接收器添加到清单。
- 安装您的应用
- 在设置>安全>设备管理员>"您的应用管理员接收器标签值"中以管理员身份启用应用
-
或者以编程方式执行 [4]
mDeviceAdminSample = new ComponentName(this,DeviceAdminSampleReceiver.class); Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample); currActivity.startActivityForResult(intent, 0);
按照参考文档中所述安装并启用设备管理员:http://developer.android.com/guide/topics/admin/device-admin.html
你错过了下面的这一行。
mDeviceAdminSample = new ComponentName(this, DeviceAdminSampleReceiver.class);
注意这些行:
Intent it = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
it.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, new ComponentName(this, YourAdminReceiver.class));
startActivityForResult(it, 0);
可以跳过。如果您不希望用户允许应用锁定屏幕,可以使用另一种方法:
adb shell dpm set-device-owner com.package/.YourAdminReceiver
现在这与OP遇到的安全异常有什么关系?
好吧,我已经将设备所有者设置为通过adb shell方式com.package/.YourAdminReceiver
,但目的与屏幕锁定不同。当我将<force-lock>
标签添加到我的设备管理员时.xml:
<uses-policies>
<limit-password />
<reset-password />
<force-lock />
</uses-policies>
我自然希望我的 locknow()
API 调用能够正常工作,但事实并非如此。我和OP一样得到了SecurityException
。奇怪,因为我的应用程序已经是设备的管理员和所有者。我通过取消设备所有者角色的设置,卸载它,然后重新安装它来使其工作。请注意,一旦通过 adb shell 设置为设备所有者,应用就只能从代码中取消设置该角色:
// mDpm.clearDeviceOwnerApp(getPackageName());
// mDpm.removeActiveAdmin(deviceAdmin);
就我而言,设备管理员是检测测试的一部分,而不是我的应用程序本身。事实证明,这是Android处理权限方式中的一个错误。解决方法是将设备管理员类、清单和策略移动到目标应用中。当然不理想,但我看不到解决方法。
你需要做3件事:
- 将
<receiver>
添加到 AndroidManifest - 为
<device-admin>
创建新的 XML 文件 - 为
DeviceAdminReceiver
创建新的 .kt 文件
这是我已经做过的答案的链接(带有示例代码):stackoverflow.com
来自 developer.android.com 的参考