关于获取android.app.role.DEVICE_POLICY_MANAGEMENT角色的技术咨询
Hey there, let's break down your problem with the android.app.role.DEVICE_POLICY_MANAGEMENT role step by step.
First off, you've confirmed your app is both an active device admin (isAdminActive() returns true) and a device owner (isDeviceOwnerApp() returns true), but you still can't get this specific role—dumpsys role shows no holders, and RoleManager.isRoleHeld() returns false. That article you found saying "Only an OEM can grant this permission to an application" is spot-on, and that's the core of your issue.
Key Details You Need to Know
This is an OEM-exclusive role
TheDEVICE_POLICY_MANAGEMENTrole is locked down at the system level for OEMs. Even if your app is a device owner or admin (which are separate from this role), regular third-party apps downloaded from the Play Store or other sources can't obtain it by default. The only way to assign this role is by modifying the device's system configuration files—specifically theconfig_devicePolicyManagementsetting that OEMs control when building custom Android images.Your current setup doesn't override this restriction
You've correctly configured your manifest with necessary permissions, intent filters, and device admin policies, but those only let your app become a device admin/owner. They don't bypass the system's OEM-only restriction for this particular role. The role's assignment isn't tied to the standard device admin provisioning flow.
Your Configuration Files for Reference
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.MANAGE_DEVICE_POLICY_TIME" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.SET_TIME_ZONE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true"> <activity android:name=".MainActivity" android:exported="true" android:lockTaskMode="if_whitelisted" android:permission="android.permission.LAUNCH_DEVICE_MANAGER_SETUP" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.app.action.ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.app.action.ROLE_HOLDER_PROVISION_MANAGED_PROFILE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.app.action.ROLE_HOLDER_PROVISION_FINALIZATION" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <receiver android:name=".AdminReceiver" android:exported="true" 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" /> <action android:name="android.intent.action.PROFILE_PROVISIONING_COMPLETE" /> </intent-filter> </receiver> </application> </manifest>
device_admin.xml
<device-admin> <uses-policies> <limit-password /> <watch-login /> <reset-password /> <force-lock /> <wipe-data /> <expire-password /> <encrypted-storage /> <disable-camera /> <disable-keyguard-features /> <reset-password /> <wipe-data /> <expire-password /> <set-global-proxy /> </uses-policies> </device-admin>
AdminReceiver.java
package com.test; import android.app.admin.DeviceAdminReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class AdminReceiver extends DeviceAdminReceiver { @Override public void onDisabled(Context context, Intent intent) { super.onDisabled(context, intent); Toast.makeText(context, "AdminReceiver.onDisabled", Toast.LENGTH_LONG).show(); } @Override public void onEnabled(Context context, Intent intent) { super.onEnabled(context, intent); Toast.makeText(context, "AdminReceiver.onEnabled", Toast.LENGTH_LONG).show(); } }
MainActivity.java (Fragment)
public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.admin).setOnClickListener(this); findViewById(R.id.test).setOnClickListener(this); } @Override public void onClick(View v) { int id = v.getId(); if(id == R.id.admin) { admin(); } else if(id == R.id.test) { test(); } } private void test() { RoleManager roleManager = getSystemService(RoleManager.class); boolean r = roleManager.isRoleHeld("android.app.role.DEVICE_POLICY_MANAGEMENT"); boolean r1 = roleManager.isRoleAvailable("android.app.role.DEVICE_POLICY_MANAGEMENT"); // Your subsequent test logic here } }
Final Takeaways
- If you're a regular third-party developer without OEM access, you can't get this role for a downloadable app. Stick with the device owner/admin permissions you already have (like
MANAGE_DEVICE_POLICY_TIME)—those should still let you implement most enterprise-style features. - If you have OEM-level access to the device's system configuration, you'll need to modify the
config_devicePolicyManagementsetting to specify your app's package name, which will allow the system to grant this role.
内容来源于stack exchange

