Usando FLAG_SHOW_WHEN_LOCKED com disableKeyguard () na tela de bloqueio do Android segura

O contexto

Recentemente, tenho procurado maneiras confiáveis ​​de controlar um protetor Android protegido. Principalmente para exibir uma tela de bloqueio personalizada. Eu sei que o Google afirmou que as telas de bloqueio personalizadas não são oficialmente suportadas pela plataforma e devem esperar que as coisas quebrem, no entanto, com as APIs existentes, acredito que deve haver maneiras de fazer isso. Eu fiz toneladas de pesquisa por cerca de uma semana, mas ainda tenho problemas aqui e ali. O que eu implementei, assumindo que um Keyguard seguro está habilitado, até agora são,

O WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED permite que uma atividade (uma janela) seja exibida na tela, colocando o Keyguard para trás e todas as ações inseguras são evitadas. Painel de notificação está desativado, terminando a atividade trará a proteção do teclado. Eu implementei como segue na minha atividade de tela de bloqueio.

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

KeyguardManager, KeyguardManager.KeyguardLock são classes obsoletas, mas elas ainda funcionam até o Jelly Bean. Para fazer isso, eu tenho umService que lida com duas coisas, segurando uma estáticaKeyguardManager e os objetos relacionados, e ele tem umBroadcastReceiver receberIntent.ACTION_SCREEN_ON eIntent.ACTION_SCREEN_OFF. (todos os objetos são inicializados corretamente)

ParaScreenReceiver

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;
        }
}

ParaBroadcastReceiver

@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();
    }
}

ParaLockScreenActivity, quando o usuário tinha inserido a senha correta,

window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
O problema

Coisas que funcionam

ACTION_ON eACTION_OFF são recebidos de forma confiável.LockScreenActivity é mostrado antes da proteção do teclado (sem manipulação do estado do telefone)Notificação não pode ser puxada para baixo, saindo da atividade de qualquer forma, seria exibido o lockscreen.

Coisas que não funcionam

Depois que eu desabiliteiKeyguard e chamada terminar (), meu aplicativo sai e homescreen ou a última atividade antes da tela foi mostrada. No entanto, sempre que eu pressionar a tecla Home, a proteção do teclado piscará na tela, descartando-se rapidamente imediatamente, e a função / evento da tecla Home normal não será manipulada (não retornará à tela inicial depois de piscar). Isso é observado quando eu toquei rapidamente na tecla Home repetidamente.

Eu até olhei para o código-fonte do Android para descobrir o manuseio da chave doméstica, mas ele nunca é enviado para aplicativos de terceiros, a menos que o tipo de janela sejaWindowManager.LayoutParams.TYPE_KEYGUARD ouWindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, que lançará o SecurityException em 4.0+, mesmo que tenha funcionado em plataformas anteriores. E para oKeyguardEu declareiDISABLE_KEYGUARD permissão use isso não deve ser o problema. Meu palpite é a bandeiraFLAG_SHOW_WHEN_LOCKED vai dizer ao sistema para lidar comKeyguard de algumas formas que entrariam em conflito com outras chamadas de desativação. Como esse sinalizador é usado principalmente para aplicativos do tipo Alarme / SMS, que é mostrar informações limitadas ao usuário, descarte-se e ative oKeyguard. Mas, no meu caso, fazer o usuário desbloquear minha tela de bloqueio e desbloquear a tela de bloqueio do sistema simplesmente anula o objetivo do meu aplicativo.

Então a questão é por que oKeyguard pisca sempre que eu pressionar Home depois que eu desativei? Existe alguma solução / solução para este problema?

P.S. Obrigado por ler uma pergunta tão longa. Esta é a primeira vez que faço uma pergunta aqui, se houver algo errado, por favor, diga-me (ou seja, formato, gramática, convenção de código, tags, etc.). Também não tive experiência com nenhum conhecimento de programação, comecei com o Android antes de saber o que é o Java. Portanto, ainda não fiz nenhum curso / treinamento adequado, essa comunidade é incrível e geralmente ajuda pessoas como eu, mesmo que sejam perguntas simples e, claro, assistir a vídeos do Google I / O, ler blogs, ler códigos de outras pessoas . Então, por favor, tolerem quaisquer erros estúpidos / erros óbvios / perguntas estúpidas. Tenho apenas 16. ^ _ ^ "

questionAnswers(5)

yourAnswerToTheQuestion