Sie können tatsächlich verhindern, dass die Statusleiste erweitert wird, ohne das Telefon zu rooten. Siehe diesen Link. Dadurch wird ein Fenster in Höhe der Statusleiste gezeichnet und alle Berührungsereignisse verbraucht.
Rufen Sie den folgenden Code direkt nach onCreate() auf.
public static void preventStatusBarExpansion(Context context) {
WindowManager manager = ((WindowManager) context.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE));
Activity activity = (Activity)context;
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
//https://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels
int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
int result = 0;
if (resId > 0) {
result = activity.getResources().getDimensionPixelSize(resId);
}
localLayoutParams.height = result;
localLayoutParams.format = PixelFormat.TRANSPARENT;
customViewGroup view = new customViewGroup(context);
manager.addView(view, localLayoutParams);
}
public static class customViewGroup extends ViewGroup {
public customViewGroup(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v("customViewGroup", "**********Intercepted");
return true;
}
}
Nette Problemumgehung, aber der obere Bereich ist für Klickereignisse deaktiviert, können Sie bitte etwas dafür vorschlagen?
– Samvel Kartashyan
25. Oktober 15 um 10:19 Uhr
@SamvelKartashyan – bearbeitete Antwort, damit das Fenster nur über die Statusleiste gezeichnet wird. Alle anderen Ereignisse sollten jetzt anklickbar sein.
– Kristy Welsh
26. Februar 16 um 15:16 Uhr
@tsiro, ja, definitiv.
– Kristy Welsh
13. September 17 um 19:22 Uhr
Wie kann ich die Statusleistenerweiterung wieder wiederherstellen?
– Mushahid Gillani
7. August 18 um 14:38 Uhr
Diese Lösung hat hervorragend funktioniert, aber nachdem ich die Ziel-SDK-Ebene auf 26 (von 23) geändert habe, erhalte ich den Fehler „android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@632ab9c – permission denied für Fenstertyp 2010″. Die App hat bereits “” Irgendwelche Ideen zur Lösung?
– Philcruz
21. Januar 19 um 0:26 Uhr
Tom
Kurze Antwort: Das ist unmöglich!
Sollte es Sie jetzt interessieren, warum dies nicht möglich ist:
Es gibt zwei Berechtigungen zum Bearbeiten der Systemstatusleiste, EXPAND_STATUS_BAR und STATUSLEISTE. Ersteres kann von jeder Anwendung angefordert werden, letzteres ist jedoch Anwendungen vorbehalten, die mit der Plattformsignatur signiert sind (Systemanwendungen, nicht von Drittanbietern). Es ist möglich um die Systemstatusleiste zu erweitern/zu reduzieren (siehe „Wie öffnet oder erweitert man die Statusleiste durch Absicht?“), aber beachten Sie, dass Reflexion erforderlich ist, da die Statusleisten-Manager Klasse ist nicht Teil des SDK. Auf die Methode disable, die vom Android-Dialer verwendet wird, um zu verhindern, dass die Statusleiste erweitert wird, kann von einer Anwendung ohne die oben erwähnte Berechtigung STATUS_BAR nicht zugegriffen werden.
Quellen: persönliche Erfahrung 🙂
Danke @farble1670 Ich bin mir sicher, dass es richtig ist. Ohne root/ zum Erstellen einer App in /system/app können Sie die Methode StatusBarMananger.disable() nicht aufrufen, ohne eine SecurityException zu erhalten.
– Tom
29. Januar 12 um 22:11 Uhr
PoOk
Zunächst, ist es unmöglich, die Statusleiste zu ändern, wenn Ihre App nicht mit dem zertifizierten Rom des Telefons signiert ist. Wenn Sie versuchen, sie zu ändern, erhalten Sie eine Sicherheitsausnahme.
Aktualisieren: In neuen APIs ist die Methode “collapsePanels” statt “collapse”.
Die einzige Möglichkeit, die ich nach mehreren Stunden Arbeit gefunden habe, besteht darin, die Methode “onWindowFocusChanged” der Aktivität zu überschreiben und, wenn sie den Fokus verliert (vielleicht hat der Benutzer die Benachrichtigungsleiste berührt), das Einklappen der Statusleiste zu erzwingen, hier ist der Code (arbeitet an einem Defy+ 2.3.5).
Sie müssen die folgende Berechtigung im Manifest deklarieren:
Aktualisieren: Sie müssen Ihren eigenen benutzerdefinierten Warndialog verwenden, indem Sie auch dessen onWindowFocusChanged-Methode überschreiben, da Warndialoge ihren eigenen Fokus haben.
Diese Methode ist so ein Hack, dass der Benutzer die Statusleiste bis zu einem gewissen Grad erweitern und dann wieder nach oben ziehen kann. Es ist besser, nur die Statusleiste mit einer Ansicht abzudecken, die alle onTouchEvents verbraucht.
– Tom
21. Juni 12 um 3:34 Uhr
Ich habe versucht, diese Problemumgehung zu verwenden, aber ich konnte nicht. Kannst du uns sagen, wie du es gemacht hast?
– Po Ok
9. Juli 12 um 12:39 Uhr
Die Antwort von Grandland Chew macht genau das, was Sie wollen, Sie überlagern die Statusleiste und akzeptieren alle Berührungseingaben.
– Tom
9. Juli 12 um 14:34 Uhr
Es funktioniert einwandfrei auf JEDER API-Ebene 4 und höher. Sie verwenden die WindowManager-Klasse, die ihre grundlegende Implementierung seit einiger Zeit NICHT geändert hat.
– Tom
11. Juli 12 um 15:42 Uhr
Es funktioniert sehr gut, aber Sie haben vergessen zu sagen, dass es erfordert
– CelinHC
21. September 12 um 15:14 Uhr
Grantland Kauen
Dies kann tatsächlich über einen kleinen Hack erfolgen, den ich zufällig entdeckt habe, erfordert jedoch die Erlaubnis android.permission.SYSTEM_ALERT_WINDOW:
Sie fügen dem WindowManager mit den bestimmten Parametern, die die Statusleiste abdecken und verhindern, dass Berührungsereignisse empfangen werden, direkt eine Ansicht in der genauen Größe der Statusleiste hinzu:
View disableStatusBarView = new View(context);
WindowManager.LayoutParams handleParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
<height of the status bar>,
// This allows the view to be displayed over the status bar
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
// this is to keep button presses going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
handleParams.gravity = Gravity.TOP;
context.getWindow().addView(disableStatusBarView, handleParams);
Dadurch wird im Grunde eine transparente Ansicht über der Statusleiste erstellt, die alle Berührungsereignisse empfängt und verhindert, dass die Ereignisse die Statusleiste erreichen, und verhindert daher, dass sie erweitert wird.
HINWEIS: Dieser Code ist ungetestet, aber das Konzept funktioniert.
Abdel Rehman
Ich habe die von genannten Lösungen ausprobiert GrantLand und PoOk aber beides hat bei mir nicht funktioniert. Eine andere Lösung zum Löschen / Verbergen der Liste der letzten Aufgaben hat den Trick für mich getan. Ich schreibe eine Launcher-App, für die ich ein aktuelles Anwendungsmenü deaktivieren musste, damit der Benutzer eine gesperrte App nicht öffnen kann. Außerdem musste ich die Erweiterung der Benachrichtigungsleiste verhindern, und dieser Trick hat mich dazu gebracht, beides zu erreichen. Überschreiben OnWindowFocusChanged Methode in Ihrer Aktivität und überprüfen Sie, ob dies das ist, was Sie wollten.
Hat bei mir in meiner Lockscreen-App funktioniert.
– nmSieger
02.03.14 um 14:34 Uhr
Die bessere Lösung ist diese: stackoverflow.com/questions/21371802/…
– Shervin Gharib
22. Juni 15 um 14:46 Uhr
Ich habe den Code auf meinem Nexus 5x 8.0 getestet und festgestellt, dass die Erweiterung der Statusleiste nicht gestoppt werden konnte. Könnten Sie ihn testen und eine andere Lösung hinzufügen? Danke.
– Lauf
13. September 18 um 9:03 Uhr
Kyle O.
Für einen Sperrbildschirm Warum verwenden Sie nicht einfach Folgendes in Ihrer Haupttätigkeit:
@Override
public void onAttachedToWindow() {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
Wenn der Benutzer keinen sicheren Sperrbildschirm eingestellt hat, lässt die App den Benutzer die Statusleiste nach unten ziehen und Aktivitäten öffnen, aber das spielt keine Rolle, da der Benutzer offensichtlich sowieso keinen sicheren Bildschirm möchte.
Wenn der Benutzer über ein sicheres Locksreen-Set verfügt, zeigt die App die Statusleiste an, lässt jedoch keine Interaktionen damit zu. Dies liegt daran, dass das Telefon tatsächlich noch gesperrt ist und nur Ihre Aktivität ausgeführt werden darf, bis der Benutzer das Telefon entsperrt. Wenn Sie Ihre App trotzdem schließen, wird der standardmäßige sichere Sperrbildschirm geöffnet. All dies ist sehr wünschenswert, da Sie nicht die ganze Zeit damit verbringen müssen, sichere Funktionen zu programmieren, von denen Sie nicht garantieren können, dass sie genauso sicher sind wie die Standardfunktionen.
Wenn Sie wirklich nicht möchten, dass der Benutzer mit der Statusleiste interagieren kann, können Sie das Flag vielleicht weglassen FLAG_DISMISS_KEYGUARD Anruf. Dann, kurz bevor Sie das Telefon entsperren wollen, setzen Sie das Flag, wie ich es im ersten Block gezeigt habe. Ich weiß nicht, ob dieser letzte Teil funktioniert, aber es ist einen Versuch wert.
hoffentlich hilft das
Hat bei mir in meiner Lockscreen-App funktioniert.
– nmSieger
02.03.14 um 14:34 Uhr
Die bessere Lösung ist diese: stackoverflow.com/questions/21371802/…
– Shervin Gharib
22. Juni 15 um 14:46 Uhr
Ich habe den Code auf meinem Nexus 5x 8.0 getestet und festgestellt, dass die Erweiterung der Statusleiste nicht gestoppt werden konnte. Könnten Sie ihn testen und eine andere Lösung hinzufügen? Danke.
– Lauf
13. September 18 um 9:03 Uhr
amalBit
Entschuldigung, aber es funktioniert nicht. verwenden FLAG_LAYOUT_IN_SCREEN verhindert, dass Sie Berührungsereignisse abfangen.
Und übrigens: Um dem Fenster eine Ansicht hinzuzufügen, verwenden Sie den Fenstermanager:
Warum willst du das verhindern?
– ingh.am
17. September 11 um 21:01 Uhr
Ich baue eine Lockscreen-Alternative. Das Herunterschieben der Benachrichtigungsleiste ist also keine Funktion eines Sperrbildschirms.
– Ye Myat Min
18. September 11 um 14:50 Uhr
LÖSUNG:> stackoverflow.com/a/25308654/2219600
– amalBit
14. August 14 um 13:52 Uhr
Google selbst gibt Ihnen Beispielcode: developer.android.com/training/system-ui/status.html
– JacksOnF1re
23. März 15 um 18:33 Uhr