Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a specific app has admin rights, and go to its admin screen?

Background

Android apps can gain some special rights using admin policies, like turning the lock screen on.

As such, those apps cannot be uninstalled till the user has revoked their admin rights.

I wish to have a function that will check if a given app (given a package name of the app) has admin rights, and if so, i will open the admin settings page of this app, to allow the user to revoke its rights.

The problem

As it turns out, there is already a function that does it.

First you get an instance of the DevicePolicyManager :

DevicePolicyManager dpm=(DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);

Then you are supposed to call isAdminActive , and get a result of true/false.

However, this function's parameter is ComponentName, meaning it needs not only the package name, but also the path to a specific class of the app.

An alternative would be to query all active admin apps, using getActiveAdmins.

Later, I you can go to the admin page using:

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

or even more specifically, to enable/disable the app admin rights :

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);

However, both of those ways seems a bit hacky, as they do not use the official API of android, that could change over android versions and roms.

The question

What's the best way to check if a given app (package name) has admin rights?

What's the best way to go to the admin page ? is there a safer way to go there? maybe a fallback mechanism from what i've done to the security screen intent (which for some reason I can't find in the API) ?


The answer

After reading the answer on this post, I've decided to share the findings:

If you wish to be safe, you can tell the user to go to the admin screen by himself, and only guide him to the security screen:

intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
context.startActivity(intent);

however, i think the next way should work for all devices:

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)
    {}

and if it fails, you can always use any of the methods i've written, and in the end, call the safe one.

like image 319
android developer Avatar asked Jan 07 '14 21:01

android developer


1 Answers

Android apps can gain some special rights using admin policies, like turning on/off the screen.

A DevicePolicyManager can lock the screen with lockNow() and set the lock timeout via setMaximumTimeToLock(), if that's what you mean.

What's the best way to check if a given app (package name) has admin rights?

See if they are in the roster returned by getActiveAdmins(). That method returns null or List of ComponentName objects, and you can call getPackageName() on a ComponentName to compare it to your target package.

What's the best way to go to the admin page ?

There is no documented and supported way to get to this portion of the Settings app. The closest thing is ACTION_SECURITY_SETTINGS.

like image 59
CommonsWare Avatar answered Sep 23 '22 17:09

CommonsWare