Использование FLAG_SHOW_WHEN_LOCKED с disableKeyguard () на защищенном экране блокировки Android

The Context

Недавно я искал надежные способы управления защищенной клавиатурой Android Keyguard. В основном для отображения пользовательского экрана блокировки. Я знаю, что Google заявил, что пользовательские экраны блокировки официально не поддерживаются платформой и должны ожидать, что что-то сломается, однако, с существующими API, я считаю, что должны быть способы сделать это. Я провел кучу исследований в течение недели, но все еще испытываю проблемы здесь и там. То, что я реализовал, предполагая, что защищенная клавиатура включена, пока

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED allows an activity(a window) to be displayed on screen on, putting the Keyguard behind, and all unsafe actions are prevented. Notification panel is disabled, finishing the activity will bring up the Keyguard. I implemented as following in my lock screen activity.

@Override
public void onAttachedToWindow() {
    window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}

KeyguardManager, KeyguardManager.KeyguardLock are deprecated classes, but they still work all the way to Jelly Bean. To do this, I have a Service that handles two things, holding a static KeyguardManager and the related objects, and have it hold a BroadcastReceiver to receive Intent.ACTION_SCREEN_ON and Intent.ACTION_SCREEN_OFF. (all the objects are initialized properly)

За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();
The Problem

Things that works

ACTION_ON and ACTION_OFF are received reliably. LockScreenActivity is shown before the Keyguard (without telephone state handling yet) Notification cannot be pulled down, exiting the activity in any way would display the lockscreen.

Things that does not work

After I disable Keyguard and call finish(), my app exits and homescreen or the last activity before the screen went off is shown. However, whenever I press the Home Key, the Keyguard will flash into the screen, quickly dismissing itself immediately, and the normal Home Key function/event is not handled (will not return to homescreen after flashing). This is observed when I rapidly tapped the Home Key repeatedly.

Я даже заглянул в исходный код Android, чтобы выяснить, как работает ключ Home, но он никогда не отправляется сторонним приложениям, если тип окна неWindowManager.LayoutParams.TYPE_KEYGUARD или жеWindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, который вызовет SecurityException на 4.0+, даже если он работал на более ранних платформах. И дляKeyguardЯ объявилDISABLE_KEYGUARD использование разрешения не должно быть проблемой. Я думаю, это флагFLAG_SHOW_WHEN_LOCKED скажет системе обработатьKeyguard в некоторых отношениях это может конфликтовать с другими вызовами отключения. Так как этот флаг в основном используется для приложения типа «Тревога / SMS», который должен показывать пользователю ограниченную информацию, затем отклонить себя и вызватьKeyguard, Но в моем случае, если пользователь разблокирует мой экран блокировки, а затем разблокирует экран блокировки системы, то это просто противоречит цели моего приложения.

So the question is why would the Keyguard flashes whenever I press Home after I disabled it? Is there any workaround/solution for this issue?

Постскриптум Спасибо, что прочитали такой длинный вопрос. Я впервые задаю здесь вопрос, если я что-то не так сделал, пожалуйста, скажите мне (например, формат, грамматика, кодовое обозначение, теги и т. Д.). Также у меня не было никакого опыта в программировании, я начал с Android, прежде чем я понял, что такое Java. Так что я еще не прошел ни одного правильного курса / обучения, это сообщество потрясающее и часто помогает таким людям, как я, даже если они простые вопросы, и, конечно, смотрю видео с Google I / O, читаю блоги, читаю другие и другие; Кодекс мне очень помогает. Поэтому, пожалуйста, терпите любые глупые ошибки / очевидные ошибки / глупые вопросы. Мне всего 16. ^ _ ^ & quot;

Ответы на вопрос(5)

Ваш ответ на вопрос