Как стереть устройство Android, когда администратор устройства деактивирован? - PullRequest
11 голосов
/ 15 февраля 2012

В моем приложении, которое является администратором устройства, мне нужно стереть все устройство, когда пользователь пытается отключить функцию администратора приложения. Когда пользователь заходит в меню «Настройки» / «Безопасность» / «Администраторы устройства» и деактивирует приложение администратора, сначала отображается диалоговое окно «Вы хотите отключить». Если пользователь говорит «да», то появляется другое маленькое диалоговое окно с текстом, предоставленным 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 (), если действие заключается в отключении администратора. Функция verifyWipeDevice () показывает другое действие с диалоговым окном. Это не показывает системное диалоговое окно для подтверждения отключения моего приложения администратора. Однако это не препятствует тому, чтобы приложение было фактически отключено!

Похоже, что система Android делает следующее:

  • Отправить ACTION_DEVICE_ADMIN_DISABLE_REQUESTED в AdminReceiver

  • Продолжить отключение администратора независимо от того, что приложение администратора хочет сделать

  • Если пользователь отменяет отключение, хорошо; если нет, приложение отключено. Приложение не может отказаться от отключения или выполнить очистку устройства после отключения.

Единственное решение на данный момент - это немедленное стирание без подтверждения, когда пользователь хочет отключить приложение администратора. Другими словами, я могу вызвать getManager (). WipeData () немедленно в onDisableRequested (). В это время админ все еще активен, и это работает.

Это правильно? Как стереть устройство, когда пользователь решает отключить приложение администратора?

Ответы [ 2 ]

4 голосов
/ 20 июня 2012

В Android 3.2 они исправили эту проблему.В Android 3.1 проблема все еще присутствовала.

Теперь (Android 3.2) в onDisabled у вас все еще есть права администратора и, таким образом, вы можете стереть устройство.

3 голосов
/ 16 февраля 2012

Моя рекомендация: Не делайте этого , если это не похоже на корпоративный тип.

Но. В onDisableRequested() вы могли бы startActivity для главного экрана, а затем startActivity для созданного вами Activity, который подтверждает, хотят они продолжать или нет. Если они выбирают «да», вы делаете это по своему усмотрению (вытрите устройство), если они говорят «нет», просто просто снова введите startActivity для главного экрана (или finish()).

Это все еще рискует тем, что они могут запустить ту же страницу настроек из недавних задач, при которой они, скорее всего, смогут нажать «да» (или ок) в диалоговом окне, которое всплыло с вашим пользовательским текстом и затем продолжите отключение администратора устройства. Чтобы попытаться избежать этого, вы можете сделать this в надежде, что он откроет страницу начальных настроек и очистит самый верхний экран администрирования отключенного устройства.

Вместо того, чтобы вытирать, вы всегда можете сделать resetPassword("new password"), а затем lockNow(). Если это приложение, связанное с безопасностью, то устройство этого человека не нужно стирать, а пароль был бы заранее задан лицом, установившим приложение.

Дайте мне знать, если у вас есть другие вопросы. Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: Я получил upvote, который напомнил мне, что этот ответ существует, поэтому я решил добавить некоторую информацию.

Вы можете использовать lockNow() в сочетании с Активом, который будет отображаться в верхней части экрана блокировки, если вы хотите заблокировать, а затем предлагать стирание или что-то еще.
А блокировка перед запуском стирания будет хорошей идеей для предотвращения проблем, если по какой-либо причине в процессе очистки произошла ошибка или задержка.

И если вы делаете что-то подобное в распределенном приложении (через магазины приложений), постарайтесь не нарушать их политику, поскольку нарушение политики МОЖЕТ вызвать постоянный бан в магазине приложений (это случилось со мной в Google Play из-за не более, чем недоразумение.)

...