2012-02-15 124 views
11

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

我试了一切,搜索了很长时间的答案,发现没有真正的解决方案。

我试了一下:

  • AdminReceiver具有功能禁止接通()。我试图擦除该功能中的设备。但是,看起来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()。在那个时候,管理员仍然活跃,这是有效的。

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

+0

我发现尝试在onDisableRequested()或onDisable()中执行wipeData()调用会使事物处于不稳定状态,并且如果屏幕关闭,则数据擦除失败。你有没有进一步的运气呢? – 2012-11-26 19:33:51

+0

如果屏幕关闭,数据擦除能否成功?我们没有测试这个。 (我们将设备更改为Android 3.2,我们可以在onDisabled中执行此操作。) – winitzki 2012-11-27 10:52:02

+0

如果我从onDisableRequested()启动了AsyncTask,我就可以使其运行。我认为,无论调用onDisableRequested()时执行什么线程,都无法可靠地在此处执行wipeData()调用。当我从AsyncTask中解雇它时,我发现几乎立即出现PowerOff对话框。 – 2012-11-27 12:46:07

回答

4

在Android 3.2的,他们有固定的这个问题。在Android 3.1中,问题仍然存在。

现在(Android 3.2)onDisabled仍然有管理员权限,所以你可以擦拭设备。

+0

这听起来像一个解决方案。你应该接受你自己的答案作为解决方案。这也会对其他人有帮助,因为那样你的问题就会被呈现给其他人,因为那些问题已经解决了,因此对那些寻求类似问题的解决方案的人来说更有趣。 – 2015-02-05 11:39:41

3

我的建议:不要做,除非它像一个企业式的东西。

不过。在onDisableRequested(),你可以startActivity的主屏幕,然后startActivityActivity您创建,确认他们是否要继续。如果他们选择是,那么你做你的愿望(擦除设备),如果他们说没有,然后就startActivity的主屏幕再次(或finish())。

这样做仍然存在风险,即他们可以从最近的任务启动相同的设置页面,在这种情况下,他们可能会在与自定义文本一起弹出的对话框中按下“是”(或ok)然后继续禁用设备管理员。为了避免发生这种情况,您可以做this,希望它能够启动初始设置页面并清除最上面的禁用设备管理屏幕。

而不是擦,你总是可以做resetPassword("new password")然后lockNow()。如果它是一个安全相关的应用程序,那么该用户的设备就不必被擦除,并且密码将由安装该应用程序的人员预先定义。

让我知道,如果您有任何其他问题。我希望这有帮助。

编辑:我得到upvote,提醒我这个答案存在,所以我想我会添加一些信息。

您可以将lockNow()与一个活动结合使用,该活动将显示在锁定屏幕的顶部,如果您想要锁定,那么仍然可以提供擦拭或其他任何内容。
在开始擦拭之前进行锁定将是一个不错的主意,以防止由于任何原因导致擦拭物出现错误或延迟的问题。

如果在分布式应用程序(通过应用程序商店)上做这样的事情,请注意不要违反其政策,因为违反政策可能导致应用程序商店永久禁止(它发生在我的Google Play上,无非个误会。)

+0

- 这是一个“类似公司的事情”:)该应用程序是必需的,以擦除设备。 - 我已经尝试开始一项新活动;但用户总是可以按“后退”并摆脱它,然后禁用管理员而无需执行任何操作。 - 如果我想重置密码并锁定,我需要成为活动管理员,因此我不能在提供确认对话框后执行此操作。 – winitzki 2012-02-16 09:12:27

+0

- 我将尝试查看如果强制启动初始设置页面会发生什么情况。 – winitzki 2012-02-16 09:17:46

+0

当我建议使用locknow时,我的意思是在将对话框显示为部分解决方案之前,如果您不想没有确认地擦拭 - 您会锁定,然后可能是主管或任何拥有密码的人。如果你可以找到一种方法来清除最近的应用程序(长按主页),那么你可以开始家庭活动,你会被设置,但我不认为有任何合法的方式来清除最近的应用程序。 – Jakar 2012-02-16 10:52:53