Programmatically deactivate a Device Admininstrato

2019-04-11 11:51发布

问题:

Is it possible to programmatically deactivate a (third-party) Device Administrator app?

I was able to retrieve all the apps with Device Administrator activated using the DevicePolicyManager and getActiveAdmins():

final DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
final List<ComponentName> adminList = dpm.getActiveAdmins();

for ( ComponentName app : adminList ) {
    Log.d(TAG, "App: ", app.getPackageName());
}

However, in order to deactivate them, I cannot use removeActiveAdmin(...), since it won't remove a component that is not my own app.

I was thinking to use an Intent and startActivity() in order to open the Device Administrator's deactivation page of that specific component I want to deactivate. Is it possible?

回答1:

Is it possible to programmatically deactivate a (third-party) Device Administrator app?

No. It is not possible to programmatically activate one, either.

I was thinking to use an Intent and startActivity() in order to open the Device Administrator's deactivation page of that specific component I want to deactivate.

There is no entry point in the Settings app to directly go to the remove-a-device-admin screen, let alone a documented Intent action for it. You can add device administrators this way, but not remove them.



回答2:

actually, it is possible to go directly to the admin screen, but i'm not sure how safe it is, as the API itself isn't available and the paths might change over different android versions and roms.

here's what i've tested:

this will go directly to the activate/de-activate screen of the app you choose:

final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminAdd"));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentName);
activity.startActivity(intent);

this will go to the list of admin apps:

final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminSettings"));
activity.startActivity(intent);

if anyone has a more official ,safer way to do it, please write it down.

those are quite risky, so you could first use this method:

Intent intent=new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
final PackageManager packageManager=context.getPackageManager();
final List<ResolveInfo> resolveInfos=packageManager.queryIntentActivities(intent,0);
if(resolveInfos!=null&&!resolveInfos.isEmpty())
  try
    {
    final ResolveInfo resolveInfo=resolveInfos.get(0);
    intent=new Intent();
    intent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,resolveInfo.activityInfo.name));
    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentNameResult);
    context.startActivity(intent);
    return true;
    }
  catch(final Exception e)
    {}

you can add try-catch for each of the methods, and if all failed , use:

final Intent intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
activity.startActivity(intent);


回答3:

This should work:

   ComponentName devAdminReceiver = new ComponentName(context, deviceAdminReceiver.class);
   DevicePolicyManager dpm = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
   dpm.removeActiveAdmin(devAdminReceiver);

You'll need to add this in manifest in your activity intent filter:

<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />