14

I'm working on an MDM (Mobile Device Management) app for android, but I have a huge problem and it's that the user can disable my app from within settings>security>device administrators. The only thing I can do about it, is display a warning message by overriding the onDisableRequested(...) method in my DeviceAdminReceiver sub-class, but I really want to prevent the user from disabling my admin app altogether.

I've tried to override the onReceive(...) method, so that nothing happens when the actions ACTION_DEVICE_ADMIN_DISABLE_REQUESTED and ACTION_DEVICE_ADMIN_DISABLED are broadcasted by the system, but so far it has not worked. Apparently some other component is processing those actions before they arrive to my onReceive(...) method and I dont know why. I would like to be able to show my own custom dialog indicating that the user can´t disable the administrator app from this section, and maybe even ask the user to set an admin password to do it.

public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_PASSWORD_CHANGED.equals(action)) {
            onPasswordChanged(context, intent);
        } else if (ACTION_PASSWORD_FAILED.equals(action)) {
            onPasswordFailed(context, intent);
        } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
            onPasswordSucceeded(context, intent);
        } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
            onEnabled(context, intent);
        } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {

        } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {

        } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
            onPasswordExpiring(context, intent);
        }
    }  

I need help to solve this issue.

Thanks,

Juan Gomez
  • 1,508
  • 1
  • 11
  • 21
shontauro
  • 1,812
  • 1
  • 25
  • 26
  • 1
    I don't think you are allowed to prevent the user from disabling the admin access for your application. – FoamyGuy Apr 01 '13 at 20:04
  • Ok, I prevented that my user disables my app as an administrator but using a Samsung SDK (You need to be a partner), It only works on Samsung Devices, in the other devices you can't avoid that the user disables your app as an administrator – shontauro Jul 29 '13 at 20:57

5 Answers5

7

You can do this from Android 5 Lollipop with the new device-owner mode. Then the Device-Administrator option in greyed-out and the user cannot disable it, thus not uninstall the device-admin App.

However note that installing a device-owner App is not easy, it has to be done at provision-time with NFC, or from a computer with adb (handy for testing but not for deployment), or with a MDM what is your case...

JBA
  • 2,889
  • 1
  • 21
  • 38
  • can you provide more info? I have access to adb and my device is rooted so how can make sure the disable option is not showing in the setting app? – Alireza Ahmadi Aug 05 '18 at 12:21
5

There is no way to prevent user from disabling, and it's his right.

But to get sure that the user himself is actually removing the admin privilege, lock the device in onDisableRequested with his password and return something like "Someone tried to disable this app administrator feature. was it you and are you sure?".

Now if someone other than the real user try to disable it, he has to enter password before proceeding.

Ali
  • 21,572
  • 15
  • 83
  • 95
  • please explain your answer more, I need to implement it, Exactly same thing as you stated in your answer, How i can lock the device in onDisableRequested, Because when onDisableRequested returns admin policy will be disabled. – Ahmad Raza Dec 10 '13 at 06:53
  • 1
    onDisableRequested, as the name suggest happens before the admin is disabled so your app can lock the device yet (if it had this permission in first place). btw, onDisabled happens after admin got disabled. @AhmadRaza – Ali Dec 11 '13 at 07:10
  • 1
    AppLock and Android parent control apps shows activity asking for password, These application display password activity before onDisabledRequested(), Do you have any idea, how these apps doing it? – Ahmad Raza Dec 11 '13 at 09:42
  • @AhmadRaza It's not possible to show it before onDisabledRequested, because how they know user is going to deactivate their admin right. But it's also possible to bring up an activity when onDisabledRequested happens, but that's not safe because user can bypass it by pressing home button, so you must manage home button too. I think locking is better. – Ali Dec 12 '13 at 00:05
  • Samsung KNOX / MDM Provides a feature or policy through which you can disable admin deactivation remotely. – Relsell May 10 '16 at 00:50
  • @Relsell Can you please direct me to api that provides to disable admin deactivation in Samsung KNOX /MDM, I am searching for that every where. Thank you in advance. – Tej Sep 25 '17 at 17:26
  • 1
    https://seap.samsung.com/sdk/knox-standard-android .. think here you can get more information what Standard and premium versions of KNOX provide. – Relsell Sep 25 '17 at 17:30
  • 1
    @Relsell got it thanks. It is `EnterpriseDeviceManager.setAdminRemovabale(booelan remoavable)` – Tej Sep 26 '17 at 17:27
3

I agree with FoamyGuy, you are not allowed to prevent disabling admin. Otherwise, your application can't be uninstalled at all.

Generally speaking a user grants to some application device admin rights and can remove these rights at any moment.

Any broadcasts are just notifications, you can't handle it and prevent some actions from happening. The system just says to listening apps that something is going on.

Also, read this:

How to wipe Android device when device admin is deactivated?

Community
  • 1
  • 1
Victor Ronin
  • 22,758
  • 18
  • 92
  • 184
3

There is a workaround to prevent disabling the device administrator. When the user initiates deactivation and we recieve ACTION_DEVICE_ADMIN_DISABLE_REQUESTED callback, we re-launch the settings activity intent.

A message is allowed by the OS to be displayed asking for confirmation from the user. According to Android OS rules, for about 5 seconds, no app is allowed to launch on top of this confirmation dialog. So basically the settings activity we tried to open will only launch after 5 seconds.

To pass these 5 seconds without allowing the user to confirm deactivation, the phone is locked by the device administrator repeatedly in a background thread. After 5 seconds when the user unlocks the device, 'Settings' activity will have been restarted.

The following code for Device Admin Broadcast Receiver Class illustrates the above method.

DevAdminReceiver.java

public class DevAdminReceiver extends DeviceAdminReceiver {
    DevicePolicyManager dpm;
    long current_time;
    Timer myThread;

    @Override
    public void onEnabled(@NonNull Context context, @NonNull Intent intent) {
        super.onEnabled(context, intent);
        Log.d("Root", "Device Owner Enabled");
    }

    @Nullable
    @Override
    public CharSequence onDisableRequested(@NonNull Context context, @NonNull Intent intent) {
        Log.d("Device Admin","Disable Requested");
        Intent startMain = new Intent(android.provider.Settings.ACTION_SETTINGS);
        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(startMain);

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

        myThread = new Timer();
        current_time = System.currentTimeMillis();
        myThread.schedule(lock_task,0,1000);

        return "Warning";
    }

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
            CharSequence res = onDisableRequested(context, intent);
            if (res != null) {
                dpm.lockNow();
                Bundle extras = getResultExtras(true);
                extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
            }
        }else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
            Log.d("Device Admin","Disabled");
        }
    }

    // Repeatedly lock the phone every second for 5 seconds
    TimerTask lock_task = new TimerTask() {
        @Override
        public void run() {
            long diff = System.currentTimeMillis() - current_time;
            if (diff<5000) {
                Log.d("Timer","1 second");
                dpm.lockNow();
            }
            else{
                myThread.cancel();
            }
        }
    };


}

Ensure force lock policy is set for the device admin in the resource file. This is a purely a workaround and not an intended solution from the side of the developers. Apps which abuse device admin permissions are always promptly taken down from the Play Store when exposed.

Complete sample code is present in the following repo
https://github.com/abinpaul1/Android-Snippets/tree/master/PermanentDeviceAdministrator

Abin K Paul
  • 163
  • 2
  • 10
2

Not a nice way to do this, but here an idea: When you receive the callback ACTION_DEVICE_ADMIN_DISABLE_REQUESTED, kill the settings app. (Search for task-killers to see how)

And make sure you don't kill the settings-app after the user entered the password.

If the settings app is gone, the user can't click the disable button.

FrankkieNL
  • 711
  • 9
  • 22