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,
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With