В последнее время я искал надежные способы управления защищенным Android Keyguard. В основном для отображения пользовательского экрана блокировки. Я знаю, что Google заявил, что пользовательские экраны блокировки официально не поддерживаются платформой, и следует ожидать, что что-то сломается, однако с существующими API я считаю, что должны быть способы сделать это. Я провел тонны исследований в течение недели, но все еще имею проблемы здесь и там. То, что я реализовал, предполагая, что защищенный Keyguard включен, пока
WindowManager.LayoutParams.FLAG _SHOW _WHEN _LOCKED позволяет отображать действие (окно )на экране, отключая блокировку клавиатуры и предотвращая все небезопасные действия. Панель уведомлений отключена, после завершения действия появится Keyguard. Я реализовал следующее в своей активности на экране блокировки.
@Override
public void onAttachedToWindow() {
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
KeyguardManager
, KeyguardManager.KeyguardLock
являются устаревшими классами, но они все еще работают вплоть до Jelly Bean. Для этого у меня есть Service
, который обрабатывает две вещи, содержит статический KeyguardManager
и связанные объекты, и содержит BroadcastReceiver
для получения Intent.ACTION_SCREEN_ON
и Intent.ACTION_SCREEN_OFF
. (все объекты инициализированы правильно)
ДляScreenReceiver
public static synchronized void disableKeyguard() {
if ( isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.disableKeyguard();
isLocked = false;
}
}
public static synchronized void reenableKeyguard() {
if ( !isLocked ) {
if ( keyguardLock == null ) {
keyguardLock = keyguardManager.newKeyguardLock(LOG_TAG);
}
keyguardLock.reenableKeyguard();
keyguardLock = null;
isLocked = true;
}
}
ДляBroadcastReceiver
@Override
public void onReceive( Context context, Intent intent ) {
if ( intent.getAction().equals(Intent.ACTION_SCREEN_ON) ) {
Intent start = new Intent(context, LockScreen.class);
start.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(start);
} else if ( intent.getAction().equals(Intent.ACTION_SCREEN_OFF) ) {
ScreenReceiverService.reenableKeyguard();
}
}
Для LockScreenActivity
, когда пользователь ввел правильный пароль,
window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
Вещи, которые работают
ACTION_ON
и ACTION_OFF
принимаются надежно.Вещи, которые не работают
Keyguard
и завершу вызов (),мое приложение закрывается, и отображается домашний экран или последнее действие перед выключением экрана. Однако всякий раз, когда я нажимаю клавишу «Домой», Keyguard будет мигать на экране, быстро закрывая себя, а обычная функция / событие «Главная клавиша» не обрабатывается (не вернется на домашний экран после мигания ). Это наблюдается, когда я несколько раз быстро нажимал клавишу «Домой».Я даже просмотрел исходный код Android, чтобы узнать, как обрабатывается домашний ключ, но он никогда не отправляется сторонним -приложениям, если только тип окна не WindowManager.LayoutParams.TYPE_KEYGUARD
или WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
, что вызовет исключение SecurityException на 4.0+, даже если оно работал на более ранних платформах. И для Keyguard
, я объявил использование разрешений DISABLE_KEYGUARD
, это не должно быть проблемой. Я предполагаю, что флаг FLAG_SHOW_WHEN_LOCKED
сообщит системе обработать Keyguard
некоторым образом, который будет конфликтовать с другими вызовами отключения. Поскольку этот флаг в основном используется для приложений типа Alarm/SMS, которые должны отображать ограниченную информацию пользователю, затем закройте себя и вызовите Keyguard
. Но в моем случае, когда пользователь разблокирует мой экран блокировки, а затем разблокирует экран блокировки системы, это просто противоречит цели моего приложения.
Итак, вопрос в том, почему Keyguard
мигает всякий раз, когда я нажимаю «Домой» после того, как отключил его? Есть ли обходной путь/решение этой проблемы?
P.S. Спасибо, что прочитали такой длинный вопрос. Я впервые задаю здесь вопрос, если я что-то сделал не так, сообщите мне (, т. е. формат, грамматику, соглашение о коде, теги и т. д. ). Также у меня не было никакого опыта в программировании, я начал с Android до того, как узнал, что такое Java. Так что я еще не прошел никакого надлежащего курса / обучения, это потрясающее сообщество и часто помогает таким людям, как я, даже если это простые вопросы, и, конечно же, просмотр видео Google I/O, чтение блогов, чтение чужого кода мне очень помогает.. Поэтому, пожалуйста, потерпите любые глупые ошибки/очевидные баги/глупые вопросы. Мне всего 16.^ _^"