Ich arbeite an einer App, in der ich ein Fenster mit einigen Informationen auf dem Sperrbildschirm (KeyGuard) anzeigen muss, ohne das Telefon zu entsperren. Ich dachte, ich könnte es wahrscheinlich mit WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG tun
Aber jedes Mal stürzt meine App mit folgendem Fehler ab:
android.view.WindowManager $ BadTokenException: Fenster android.view.ViewRootImpl$W@40ec8528 kann nicht hinzugefügt werden - Berechtigung für diesen Fenstertyp verweigert
Diese Beiträge ( hier , hier und hier ) geben alle die gleiche Antwort. So fügen Sie der Manifest-Datei die folgende Berechtigung hinzu
android.permission.SYSTEM_ALERT_WINDOW
Lösung, die ich implementiert habe, aber immer noch den gleichen Fehler erhalte. Irgendeine Idee, was ich falsch mache?
Hier sind die Berechtigungen in meiner Manifestdatei:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.droidpilot.keyguardwindow" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
Und dies ist der Code, mit dem ich das Fenster zum Sperrbildschirm hinzufüge
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = mInflater.inflate(R.layout.lock_screen_notif, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
wm.addView(mView, params);
Hat jemand eine Idee?
PS Ich teste auf einem HTC Desire 620 DS mit Android 4.4.2
quelle
Wenn Sie verwenden
apiLevel >= 19
, verwenden Sie nichtwelches den folgenden Fehler bekommt:
Verwenden Sie stattdessen Folgendes:
quelle
TYPE_SYSTEM_ALERT
gut auf Android 5.1 mit demandroid.permission.SYSTEM_ALERT_WINDOW
im Manifest gewährten funktioniert .android.permission.SYSTEM_ALERT_WINDOW
mitLayoutParams.TYPE_TOAST
?Ich denke, Sie sollten das Ziel unterscheiden (vor und nach Oreo)
quelle
Build.VERSION_CODES.O
& nicht erkennenWindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
. Meine targetSdkVersion ist 26Ich habe mein Bestes gegeben, um alle für diese Ausgabe verfügbaren Beispiele auszuprobieren. Endlich habe ich die Antwort darauf bekommen. Ich weiß nicht, wie zuverlässig es ist, aber meine App stürzt jetzt nicht ab.
Geben Sie in Ihrer Manifestdatei einfach die Erlaubnis ein
Zusätzlich können Sie auch nach der API-Ebene suchen, wenn sie dann> = 23 ist
Ich hoffe es hilft jemandem irgendwo. Vollständiges Beispiel https://anam-android-codes.blogspot.in/?m=1
quelle
Für Android API Level 8.0.0 sollten Sie verwenden
anstatt
oder
SYSTEM_ALERT
.quelle
Versuchen Sie, dass dieser Code perfekt funktioniert
quelle
Suche
in Ihrer Einstellung und aktivieren Sie Ihre App. Versuchen Sie es für Android 8 Oreo
quelle
Zunächst stellen Sie sicher, dass Sie über die Berechtigung zum Hinzufügen in der Manifestdatei verfügen.
Überprüfen Sie, ob die Anwendung über die Berechtigung anderer Apps verfügt oder nicht. Diese Berechtigung ist standardmäßig für API <23 verfügbar. Für API> 23 müssen Sie jedoch zur Laufzeit nach der Berechtigung fragen.
Verwenden Sie diesen Code:
}}
quelle
Ändern Sie Ihr Flag Windowmanger-Flag "TYPE_SYSTEM_OVERLAY" in Ihrem Projekt in "TYPE_APPLICATION_OVERLAY", um die Kompatibilität mit Android O zu gewährleisten
WindowManager.LayoutParams.TYPE_PHONE
zuWindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
quelle
Ich habe es geschafft, endlich ein Fenster auf dem Sperrbildschirm mit der Verwendung von
TYPE_SYSTEM_OVERLAY
anstelle von anzuzeigenTYPE_KEYGUARD_DIALOG
. Dies funktioniert wie erwartet und fügt das Fenster auf dem Sperrbildschirm hinzu.Das Problem dabei ist, dass das Fenster über alles hinzugefügt wird, was es kann. Das heißt, bei sicheren Sperrbildschirmen wird das Fenster sogar über Ihrer Tastatur- / Mustersperre angezeigt. Bei einem ungesicherten Sperrbildschirm wird dieser über der Benachrichtigungsleiste angezeigt, wenn Sie ihn über den Sperrbildschirm öffnen.
Für mich ist das inakzeptabel. Ich hoffe, dass dies allen anderen helfen kann, die mit diesem Problem konfrontiert sind.
quelle
TYPE_SYSTEM_OVERLAY
. Mein setOnDismissListener in AlertDialog wird nicht aufgerufen.Ich habe gerade eine einfache Ansicht
WindowManager
mit den folgenden Schritten hinzugefügt :Damit können Sie WM eine Ansicht hinzufügen.
Getestet in Pie.
quelle
LayoutParams.TYPE_PHONE ist veraltet. Ich habe meinen Code wie folgt aktualisiert.
LayoutParams.TYPE_APPLICATION_OVERLAY erfordert API-Level 26 oder höher.
quelle
Der Hauptgrund für die Verweigerung der Berechtigung ist, dass wir keine Berechtigung zum Zeichnen über andere Apps haben. Wir müssen die Berechtigung zum Zeichnen über andere Apps bereitstellen, die mit dem folgenden Code ausgeführt werden kann
Code für die Erlaubnis anfordern
Fügen Sie dies in Ihre MainActivity ein
Fügen Sie dies auch hinzu
quelle
Ich hatte Mühe, die funktionierende Lösung mit
ApplicationContext
und zu finden,TYPE_SYSTEM_ALERT
und fand verwirrende Lösungen.getApplicationContext()
Wenn Sie möchten, dass der Dialog von einer Aktivität aus geöffnet wird, ist auch der Dialog ein Singleton, den Sie verwenden müssen , und wenn Sie möchten, dass der Dialog sein soll, müssenTYPE_SYSTEM_ALERT
Sie die folgenden Schritte ausführen ::Holen Sie sich zuerst die Instanz des Dialogs mit dem richtigen Thema. Außerdem müssen Sie die Versionskompatibilität wie in meinem folgenden Snippet verwalten:
Nachdem Sie den Titel, die Nachricht und die Schaltflächen festgelegt haben, müssen Sie den Dialog wie folgt erstellen:
Jetzt
type
spielt das hier die Hauptrolle, da dies der Grund für den Absturz ist, habe ich die Kompatibilität wie folgt behandelt:Hinweis : Wenn Sie einen benutzerdefinierten Dialog mit
AppCompatDialog
den folgenden Optionen verwenden:Sie können Ihren Typ für die
AppCompatDialog
Instanz wie folgt direkt definieren :Vergessen Sie nicht, die Manifest-Berechtigung hinzuzufügen:
quelle
quelle