13

我正在开发适用于 android 的 MDM(移动设备管理)应用程序,但我有一个大问题,用户可以从设置>安全>设备管理员中禁用我的应用程序。我唯一能做的就是通过覆盖onDisableRequested(...)我的DeviceAdminReceiver子类中的方法来显示警告消息,但我真的想阻止用户完全禁用我的管理应用程序。

我试图覆盖该onReceive(...)方法,以便当系统广播操作 ACTION_DEVICE_ADMIN_DISABLE_REQUESTED 和 ACTION_DEVICE_ADMIN_DISABLED 时没有任何反应,但到目前为止它还没有起作用。显然,其他一些组件在这些操作到达我的onReceive(...)方法之前正在处理它们,我不知道为什么。我希望能够显示我自己的自定义对话框,指示用户无法从此部分禁用管理员应用程序,甚至可能要求用户设置管理员密码来执行此操作。

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

我需要帮助来解决这个问题。

谢谢,

4

5 回答 5

7

您可以使用新的设备所有者模式从 Android 5 Lollipop 执行此操作。然后设备管理员选项灰显,用户无法禁用它,因此不卸载设备管理员应用程序。

但是请注意,安装设备所有者应用程序并不容易,它必须在配置时使用 NFC 完成,或者从带有 adb 的计算机(便于测试但不用于部署)或使用 MDM 完成。 ..

于 2015-07-10T09:37:06.833 回答
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.

于 2013-05-16T00:45:42.893 回答
3

我同意 FoamyGuy,不允许您阻止禁用管理员。否则,您的应用程序根本无法卸载。

一般来说,用户授予某些应用设备管理员权限,并且可以随时删除这些权限。

任何广播都只是通知,您无法处理它并阻止某些操作发生。系统只是对正在监听的应用程序说正在发生的事情。

另外,请阅读:

停用设备管理员后如何擦除 Android 设备?

于 2013-04-01T20:27:06.990 回答
2

有一种解决方法可以防止禁用设备管理员。当用户启动停用并且我们收到 ACTION_DEVICE_ADMIN_DISABLE_REQUESTED 回调时,我们重新启动设置活动意图。

操作系统允许显示一条消息,要求用户确认。根据 Android 操作系统规则,大约 5 秒内,不允许在此确认对话框之上启动任何应用程序。所以基本上我们试图打开的设置活动只会在 5 秒后启动。

为了在不让用户确认停用的情况下经过这 5 秒,手机会被设备管理员在后台线程中反复锁定。用户解锁设备 5 秒后,“设置”活动将重新启动。

Device Admin Broadcast Receiver Class 的以下代码说明了上述方法。

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


}

确保force lock在资源文件中为设备管理员设置了策略。这纯粹是一种解决方法,而不是开发人员的预期解决方案。滥用设备管理员权限的应用程序在暴露时总是会立即从 Play 商店中删除。

完整的示例代码位于以下 repo
https://github.com/abinpaul1/Android-Snippets/tree/master/PermanentDeviceAdministrator

于 2020-04-24T18:12:32.277 回答
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.

于 2017-07-18T06:03:55.960 回答