Использование FLAG _SHOW _WHEN _LOCKED with disableKeyguard ()на защищенном экране блокировки Android

Контекст

В последнее время я искал надежные способы управления защищенным 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принимаются надежно.
    • LockScreenActivity отображается перед Keyguard (без обработки состояния телефона )
    • . Уведомление не может быть снято, любой выход из активности приведет к отображению экрана блокировки.
  • Вещи, которые не работают

    • После того, как я отключу 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.^ _^"

25
задан userM1433372 12 January 2016 в 07:28
поделиться