webentwicklung-frage-antwort-db.com.de

So erstellen Sie in Android immer eine Vollbild-Overlay-Aktivität

Ich möchte in der Lage sein, eine Aktivität zu erstellen, die sich immer vorne auf dem Display von Android befindet. Sie sollte keine Eingaben erhalten. Übergeben Sie sie einfach an die nächste darunter liegende Anwendung. So etwas wie ein HUD.

Ich konnte herausfinden, dass ich den zugrunde liegenden Fenstertyp auf TYPE_SYSTEM_ALERT setzen muss, aber es sieht so aus, als würde Android meinen Code ignorieren - es wird keine Ausnahme ausgelöst, selbst wenn ich die Berechtigung Android.permission.SYSTEM_ALERT_WINDOW aus dem Manifest lösche. (es ist erforderlich, diesen Fenstertyp zu verwenden). Als ich versucht habe, den ALERT-Typ im Dialog zu verwenden, hat es gut funktioniert, aber ich kann den Dialog nicht in ein transparentes Ganzes gestalten. Hier ist mein Code, vielleicht fehlt etwas einfaches.

public void onCreate(Bundle savedInstanceState) {       
     super.onCreate(savedInstanceState);        

     requestWindowFeature(Window.FEATURE_NO_TITLE);
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
     getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);             
     getWindow().setBackgroundDrawableResource(Android.R.color.transparent);
     getWindow().setFormat(PixelFormat.TRANSLUCENT);
     setContentView(R.layout.main);
}

Die Transluzenz-Einstellung muss in XML-Manifest extern aktiviert werden, ansonsten hat es auch nicht funktioniert.

 <item name="Android:windowIsTranslucent">true</item>
19
tmouse
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);

WindowManager wm = (WindowManager) getApplicationContext()
    .getSystemService(Context.WINDOW_SERVICE);

ViewGroup mTopView = (ViewGroup) App.inflater.inflate(R.layout.main, null);
getWindow().setAttributes(params);
wm.addView(mTopView, params);
24
tmouse

Ich habe festgestellt, dass die akzeptierte Antwort (von mouse) für mich nicht ganz funktioniert hat. Vielleicht hat es für ein älteres API-Level funktioniert? Ich benutze API Level 24.

Diese besondere Antwort hatte empfohlen:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
    PixelFormat.TRANSLUCENT
);

Es gibt ein Problem damit. Die Konstruktoren, die für WindowManager.LayoutParams existieren, lauten wie folgt:

 enter image description here

Das WindowManager.LayoutParams.FLAG_FULLSCREEN-Flag wird also als expliziter Wert für int w und int h verwendet. Das ist nicht gut! Die Bemaßungen Ihrer Ansicht werden auf 1024 * 1024 gesetzt, sodass der Bildschirm nicht fill wird. Und selbst wenn Sie explizit die Breite und Höhe des Layouts an die Abmessungen des Geräts anpassen: Sie werden nicht aktualisiert, wenn sich die Bildschirmausrichtung ändert. Wir brauchen einen anderen Ansatz…


Ich habe festgestellt, dass die korrekte - Konstruktion für ein Vollbild-Overlay folgendermaßen aussieht:

final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, // TYPE_SYSTEM_ALERT is denied in apiLevel >=19
    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_FULLSCREEN,
    PixelFormat.TRANSLUCENT
);

Dies bedeutet, dass wir nicht mehr explizit Breite und Höhe angeben. Das Layout basiert stattdessen vollständig auf unseren Flaggen.

Ja, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN ist noch ein erforderliches Flag. es ist notwendig, wenn Sie über Dekorationen wie die Statusleiste zeichnen möchten.

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY sollte anstelle von TYPE_SYSTEM_ALERT in API-Ebene> = 19 verwendet werden. Dies ist eine Notiz, die ich vor einiger Zeit geschrieben habe. Leider konnte ich nicht Zitat finden, um zu bestätigen, warum ich das dachte, also nehmen Sie das mit einer Prise Salz.


Bonus-Notizen (wenn Sie dies lesen, versuchen Sie wahrscheinlich, eine Vollbild-Überlagerung zu erstellen):

Ihr Manifest benötigt diese Berechtigungen (Erklärung hier ):

<uses-permission Android:name="Android.permission.ACTION_MANAGE_OVERLAY_PERMISSION"/>
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/>

Ich verstehe, dass SYSTEM_ALERT_WINDOW die eigentliche Berechtigung ist, aber ACTION_MANAGE_OVERLAY_PERMISSION auch erforderlich ist: Sie können zur Laufzeit anfordern, dass der Benutzer das SYSTEM_ALERT_WINDOW-Privileg erteilt.

Ich gebe here den Quellcode für meine funktionierende API Level 24-App, die eine Vollbild-Overlay erstellt.

2
Birchlabs

Schau dir das an

erwähnen Sie es in Ihrer AndroidManifest.xml-Datei

<activity Android:name=".MyActivity" Android:theme="@Android:style/Theme.NoTitleBar.Fullscreen" />

wenn Sie Ihre Aktivität auch auf dem gesamten Bildschirm transparent machen möchten

schau dir das an

<activity Android:name=".MyActivity" Android:theme="@Android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
0
Ravi1187342