Android SDK26+程序化重置锁屏密码遇SecurityException问题求助
这个报错的核心原因很明确:你的设备管理员只是普通的设备管理权限持有者,并非托管配置文件(Managed Profile)的所有者。在Android 8.0(API26)及以上版本中,setResetPasswordToken和resetPasswordWithToken这两个API是专门给托管配置文件所有者(Profile Owner)使用的,普通设备管理员没有调用权限,所以会抛出does not own the profile的异常。
下面给你两种针对性的解决方案,根据你的业务场景选择:
方案一:将应用设置为托管配置文件所有者(适用于工作资料场景)
如果你的应用是面向企业工作资料管理的,需要先把设备管理员设置为Profile Owner。调试阶段可以通过ADB命令快速设置:
dpm set-profile-owner com.xxx.xxx/com.xxx.xxxx.MyAdmin
注意:执行这个命令前,设备不能已有其他托管配置文件,否则需要先清除现有配置。正式部署则需要通过Android Enterprise的官方流程来配置。
设置完成后,你的应用就能正常调用setResetPasswordToken和resetPasswordWithToken方法修改配置文件内的锁屏密码了。
方案二:改用resetPassword方法(适用于设备所有者场景)
如果你的应用不需要管理工作资料,只是想修改设备全局的锁屏密码,那么需要先让应用成为设备所有者(Device Owner),然后直接使用resetPassword方法,不需要token:
@TargetApi(21) private void changePasswordDirectly() { DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getApplicationContext().getSystemService(DEVICE_POLICY_SERVICE); if (devicePolicyManager != null) { // 先检查是否是设备所有者 if (devicePolicyManager.isDeviceOwnerApp(getPackageName())) { // 修改密码为"1234",标志位0表示无特殊限制(可根据需求传如RESET_PASSWORD_REQUIRE_ENTRY等) boolean isSuccess = devicePolicyManager.resetPassword("1234", 0); if (isSuccess) { // 密码修改成功的逻辑 } else { // 密码修改失败,可能是密码不符合系统复杂度要求等 } } else { // 不是设备所有者,无法修改密码 } } }
划重点:普通的设备管理员(通过ACTION_ADD_DEVICE_ADMIN申请的权限)没有调用
resetPassword的权限,只有Device Owner或Profile Owner才有这个权限。
额外检查:确认你的管理员权限类型
可以通过以下代码快速确认当前应用的管理员身份:
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); boolean isDeviceOwner = dpm.isDeviceOwnerApp(getPackageName()); boolean isProfileOwner = dpm.isProfileOwnerApp(getPackageName()); Log.d("AdminCheck", "设备所有者:" + isDeviceOwner + " | 配置文件所有者:" + isProfileOwner);
最后补充一点:普通安装的应用无法在已使用的设备上成为Device Owner,通常需要在设备首次启动的开箱流程中设置,或者通过ADB命令调试使用。
内容的提问来源于stack exchange,提问作者dudi

