Verwendung von FLAG_SHOW_WHEN_LOCKED mit disableKeyguard () im gesicherten Android-Sperrbildschirm

Der Kontext

Vor kurzem habe ich nach zuverlässigen Möglichkeiten gesucht, um einen gesicherten Android-Keyguard zu steuern. Hauptsächlich zur Anzeige eines benutzerdefinierten Sperrbildschirms. Ich weiß, dass Google angegeben hat, dass benutzerdefinierte Sperrbildschirme nicht offiziell von der Plattform unterstützt werden und dass damit zu rechnen ist, dass bei den vorhandenen APIs Probleme auftreten. Ich bin jedoch der Meinung, dass es hierfür Möglichkeiten geben muss. Ich habe eine Woche lang jede Menge Nachforschungen angestellt, aber immer noch hier und da Probleme. Was ich implementiert habe, unter der Annahme, dass ein gesicherter Keyguard aktiviert ist, sind:

Mit WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED kann eine Aktivität (ein Fenster) auf dem Bildschirm angezeigt werden, wobei der Keyguard zurückgesetzt wird, und alle unsicheren Aktionen werden verhindert. Das Benachrichtigungsfeld ist deaktiviert. Wenn Sie die Aktivität beenden, wird die Tastensperre angezeigt. Ich habe Folgendes in meiner Aktivität zum Sperren von Bildschirmen implementiert.

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

KeyguardManager, KeyguardManager.KeyguardLock sind veraltete Klassen, aber sie funktionieren immer noch bis zu Jelly Bean. Dazu habe ich eineService das behandelt zwei Dinge, die eine statische haltenKeyguardManager und die verwandten Objekte, und lassen Sie es halten einBroadcastReceiver bekommenIntent.ACTION_SCREEN_ON undIntent.ACTION_SCREEN_OFF. (Alle Objekte werden ordnungsgemäß initialisiert.)

ZumScreenReceiver

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

ZumBroadcastReceiver

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

ZumLockScreenActivity, wenn der Benutzer den richtigen Passcode eingegeben hatte,

window.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
ScreenReceiverService.disableKeyguard();
finish();
Das Problem

Dinge, die funktionieren

ACTION_ON undACTION_OFF werden zuverlässig empfangen.LockScreenActivity wird vor dem Keyguard angezeigt (noch ohne Behandlung des Telefonstatus)Die Benachrichtigung kann nicht heruntergezogen werden. Wenn Sie die Aktivität in irgendeiner Weise beenden, wird der Sperrbildschirm angezeigt.

Dinge, die nicht funktionieren

Nachdem ich deaktiviert habeKeyguard und Anruf beenden (), meine App wird beendet und der Homescreen oder die letzte Aktivität, bevor der Bildschirm ausgeht, wird angezeigt. Wenn ich jedoch die Starttaste drücke, blinkt die Tastensperre auf dem Bildschirm und wird sofort wieder ausgeblendet. Die normale Starttastenfunktion / das normale Ereignis wird nicht verarbeitet (kehrt nach dem Blinken nicht zum Startbildschirm zurück). Dies wird beobachtet, wenn ich wiederholt schnell auf die Home-Taste tippte.

Ich habe sogar in den Android-Quellcode geschaut, um herauszufinden, wie der Startschlüssel gehandhabt wird, aber er wird niemals an Anwendungen von Drittanbietern gesendet, es sei denn, der Fenstertyp istWindowManager.LayoutParams.TYPE_KEYGUARD oderWindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, der SecurityException auf 4.0+ auslöst, auch wenn es auf früheren Plattformen funktioniert hat. Und für dieKeyguardHabe ich erklärtDISABLE_KEYGUARD Erlaubnis verwenden, sollte dies nicht das Problem sein. Meine Vermutung ist die FlaggeFLAG_SHOW_WHEN_LOCKED wird das System anweisen, damit umzugehenKeyguard In gewisser Weise würde dies zu Konflikten mit anderen Deaktivierungsaufrufen führen. Da dieses Flag hauptsächlich für Anwendungen vom Typ Alarm / SMS verwendet wird, bei denen dem Benutzer nur begrenzte Informationen angezeigt werden sollen, schließen Sie sich selbst und rufen Sie das aufKeyguard. Aber in meinem Fall hat das Entsperren des Sperrbildschirms durch den Benutzer und das Entsperren des System-Sperrbildschirms nur den Zweck meiner App verloren.

Die Frage ist also, warum das so istKeyguard blinkt, wenn ich nach dem Deaktivieren auf Home drücke? Gibt es eine Problemumgehung / Lösung für dieses Problem?

P.S. Vielen Dank für das Lesen einer so langen Frage. Dies ist das erste Mal, dass ich hier eine Frage stelle. Wenn ich etwas falsch gemacht habe, sagen Sie es mir bitte (z. B. Format, Grammatik, Codekonvention, Tags usw.). Auch ich hatte keine Erfahrung mit Programmierkenntnissen, ich habe mit Android angefangen, bevor ich weiß, was Java ist. Ich habe noch keinen richtigen Kurs / Training absolviert. Diese Community ist fantastisch und hilft Leuten wie mir oft, auch wenn es sich um einfache Fragen handelt. Natürlich hilft es mir sehr, wenn ich mir Google I / O-Videos ansehe, Blogs lese oder den Code anderer lese . Dulden Sie also bitte dumme Fehler / offensichtliche Fehler / dumme Fragen. Ich bin erst 16. ^ _ ^ "

Antworten auf die Frage(5)

Ihre Antwort auf die Frage