Как стереть устройство Android, когда администратор устройства отключен?

В моем приложении, которое является администратором устройства, мне нужно стереть все устройство, когда пользователь пытается отключить функцию администратора приложения. Когда пользователь переходит к настройкам /Security/Device admins и деактивирует приложение admin, сначала появляется диалоговое окно "Вы хотите деактивировать". Если пользователь говорит "да" , тогда появляется еще один небольшой диалог с текстом, предоставленным приложением 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() показывает другое действие с диалогом. Это не показывает системный диалог для подтверждения отключения моего приложения admin. Однако это не помешает отключению приложения!

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

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

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

  • Если пользователь отменяет отключение, штраф; если нет, приложение отключено. Невозможно отключить приложение или отключить его при отключении.

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

Сообщите мне, если у вас есть другие вопросы. Надеюсь, это поможет.

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

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

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