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

发布于 2025-01-05 10:34:36 字数 1817 浏览 0 评论 0原文

在我的设备管理应用程序中,当用户尝试停用应用程序的管理功能时,我需要擦除整个设备。当用户转到“设置”/“安全”/“设备管理”并停用管理应用程序时,首先会出现一个对话框“您要停用吗”。如果用户说“是”,则会出现另一个小对话框,其中包含应用程序的 AdminReceiver 在 onDisableRequested() 中提供的文本。如果用户随后说“是”,我想擦除整个设备。如何做到这一点?

我尝试了一切,寻找答案很长时间,但没有找到真正的解决方案。

我尝试过的:

  • AdminReceiver 有一个函数 onDisable()。我尝试在该功能中擦除设备。然而,onDisable() 似乎是在管理员被禁用之后调用的。因此应用程序根本无法使用wipeData()函数(抛出安全异常)。我还验证了 isAdminActive() 当时返回 false。

官方文档没有明确说明这一点,但似乎在调用 onDisable() 时管理员已经被禁用。因此我们必须在那之前擦除设备。

  • AdminReceiver有一个函数onDisableRequested(),它返回CharSequence。我尝试在该功能中放置另一个警报框。这会崩溃,因为无法从非活动上下文中调用警报框,这似乎就是我们在 onDisableRequested() 中时所拥有的。

  • AdminReceiver 有一个函数 onReceive(),任何事件都会调用该函数。同样,在此函数中,我们不在活动上下文中,无法呈现我们自己的对话框。

  • 我尝试从 onReceive() 创建另一个活动。这有效;在 onReceive() 期间,当我们收到 ACTION_DISABLE_ADMIN_REQUESTED 时,管理员仍然处于活动状态,我们可以擦除设备。但是,系统仍然会显示自己的对话框,询问用户是否停用管理员。如果用户对我们的对话框说“不”,但对系统对话框说“是”,则管理员将被停用,我们将无法擦除设备。

我在 DeviceAdminReceiver 的子类中尝试了以下操作:

@Override
public void onReceive(Context context, Intent intent) {
 // detect whether disabling is requested?
 if (intent.getAction().equals(ACTION_DEVICE_ADMIN_DISABLE_REQUESTED)) {
            confirmWipeDevice(context);

 } else {
    super.onReceive(context, intent);
 }      
}

换句话说,如果操作是禁用管理员,我不会调用 super.onReceive() 。函数confirmWipeDevice() 通过对话框显示不同的活动。这不会显示用于确认禁用我的管理应用程序的系统对话框。但是,这并不能阻止该应用程序被实际禁用!

Android 系统似乎执行以下操作:

  • 将 ACTION_DEVICE_ADMIN_DISABLE_REQUESTED 发送到 AdminReceiver

  • 无论管理应用程序想要做什么,都继续禁用管理

  • 如果用户取消禁用,很好;如果没有,该应用程序将被禁用。应用程序无法拒绝禁用,也无法在禁用时执行设备擦除。

到目前为止,唯一的解决方案是当用户想要禁用管理应用程序时立即擦除而不进行确认。换句话说,我可以在 onDisableRequested() 中立即调用 getManager().wipeData() 。那时,管理员仍然处于活动状态并且这有效。

这是正确的吗?当用户选择禁用管理应用程序时如何擦除设备?

In my application, which is a device admin, I need to wipe the entire device when the user tries to deactivate the admin function of the application. When the user goes to Settings / Security / Device admins and deactivates the admin app, first a dialog is presented "Do you want to deactivate". If the user says "yes", then another small dialog is presented, with the text provided by the application's AdminReceiver in onDisableRequested(). If the user then says "yes", I want to wipe the entire device. How to accomplish this?

I tried everything, searched long for answers, found no real solutions.

What I tried:

  • AdminReceiver has a function onDisable(). I tried to wipe the device in that function. However, it appears that onDisable() is called after the admin has been disabled. Thus the app cannot use the wipeData() function at all (a security exception is thrown). I have also verified that isAdminActive() returns false at that time.

Official documentation does not say this clearly, but it seems that the admin is already disabled when onDisable() is called. Thus we have to wipe the device before that time.

  • AdminReceiver has a function onDisableRequested(), which returns CharSequence. I tried to put another alert box in that function. This crashes because an alert box cannot be called from a non-activity context, which seems to be what we have when we are in onDisableRequested().

  • AdminReceiver has a function onReceive(), which gets called on any events. In this function, again, we are not in an activity context and cannot present our own dialogs.

  • I tried creating another activity from onReceive(). This works; during onReceive() when we get ACTION_DISABLE_ADMIN_REQUESTED, the admin is still active and we can wipe the device. However, the system still presents its own dialog asking the user whether to deactivate the admin. If the user says no to our dialog but yes to the system dialog, the admin will be deactivated and we will have failed to wipe the device.

I tried the following, in my subclass of DeviceAdminReceiver:

@Override
public void onReceive(Context context, Intent intent) {
 // detect whether disabling is requested?
 if (intent.getAction().equals(ACTION_DEVICE_ADMIN_DISABLE_REQUESTED)) {
            confirmWipeDevice(context);

 } else {
    super.onReceive(context, intent);
 }      
}

In other words, I do not call super.onReceive() if the action is to disable the admin. The function confirmWipeDevice() shows a different activity with a dialog. This does not show the system dialog for confirming the disabling of my admin app. However, this does not prevent the app from being actually disabled!

It seems that the Android system does the following:

  • Send ACTION_DEVICE_ADMIN_DISABLE_REQUESTED to the AdminReceiver

  • Proceed with disabling the admin regardless of what the admin app wants to do

  • If the user cancels the disabling, fine; if not, the app is disabled. There is no way for the app to refuse being disabled, or to perform the device wipe upon disabling.

The only solution so far is to wipe immediately without confirmation when the user wants to disable the admin app. In other words, I can call getManager().wipeData() immediately in onDisableRequested(). At that time, the admin is still active and this works.

Is this correct? How to wipe the device when the user chooses to disable the admin app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦屿孤独相伴 2025-01-12 10:34:36

我的建议:不要这样做,除非它是公司类型的事情。

但。在 onDisableRequested() 中,您可以在主屏幕上 startActivity,然后在您创建的 Activity 上使用 startActivity确认他们是否要继续。如果他们选择“是”,那么您可以按照自己的意愿进行操作(擦除设备),如果他们说“否”,则只需再次启动主屏幕(或“完成()”) 。

这仍然存在风险,他们可以从最近的任务启动相同的设置页面,在这种情况下,他们可能能够在弹出的带有自定义文本的对话框上按“是”(或确定),然后继续禁用设备管理。为了尝试避免这种情况发生,您可以执行此操作,希望它能够启动初始设置页面并清除顶部- 最禁用设备管理屏幕。

您可以随时执行 resetPassword("new password"),然后执行 lockNow(),而不是擦除。如果它是与安全相关的应用程序,则不必擦除该人的设备,并且密码将由安装该应用程序的人预先定义。

如果您还有其他问题,请告诉我。我希望这有帮助。

编辑:我得到了一个赞成票,提醒我这个答案存在,所以我想我应该添加一些信息。

您可以将 lockNow() 与 Activity 结合使用,该 Activity 将显示在锁定屏幕顶部(如果您想锁定),然后仍然提供擦除或其他任何操作。
在开始擦除之前锁定是一个好主意,可以防止擦除由于任何原因出现错误或延迟时出现问题。

如果在分布式应用程序(通过应用程序商店)上执行类似的操作,请注意不要违反他们的政策,因为违反政策可能会导致应用程序商店永久禁止(我在 Google Play 上发生过这种情况,原因不外乎一个误会。)

My recommendation: Don't do that unless it's like a corporate-type thing.

But. In onDisableRequested(), you could startActivity for the home screen, and then startActivity for an Activity you created that confirms whether they want to continue or not. If they choose yes, then you do as you desire (wipe the device), if they say no, then just startActivity for the home screen again (or finish()).

This does still run the risk that they can launch the same settings page from the recent tasks, under which circumstance they will likely be able to press "yes" (or ok) on the dialog that popped up with your custom text and then continue with disabling device admin. To try and avoid that from happening, you could do this in the hopes it will start the initial settings page and clear the top-most disable device admin screen.

Instead of wiping, you could always do resetPassword("new password") and then lockNow(). If it's a security-related app, then the person's device doesn't have to be wiped, and the password would have been pre-defined by the person who installed the app.

Let me know if you have any other questions. I hope this helps.

EDIT: I got an upvote that reminded me this answer exists, so I figured I'd add some info.

You could use lockNow() in conjunction with an Activity that will show on top of the lock screen if you want to lock then still offer the wipe or whatever else.
And locking before starting the wipe would be a good idea to prevent problems if the wipe has an error or delay for any reason.

And if doing anything like this on a distributed app (via app stores), take care not to violate their polices because a policy violation CAN cause a permanent ban from the app store (it happened to me on Google Play, due to nothing more than a misunderstanding.)

宫墨修音 2025-01-12 10:34:36

在 Android 3.2 中他们已经解决了这个问题。在 Android 3.1 中,该问题仍然存在。

现在 (Android 3.2),在 onDisabled 中,您仍然拥有管理员权限,因此您可以擦除设备。

In Android 3.2 they have fixed this problem. In Android 3.1 the problem was still present.

Now (Android 3.2) in onDisabled you still have admin privileges and so you can wipe the device.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文