Android: Wie kann ich den Bildschirm programmgesteuert ein- und ausschalten?

97

Bevor ich diesen Beitrag als "Duplikat" markiere, schreibe ich diesen Beitrag, da kein anderer Beitrag die Lösung des Problems enthält.

Ich versuche, das Gerät auszuschalten und nach einigen Minuten oder einem Sensorwechsel wieder einzuschalten.

Deaktivieren Sie die Anzeigetests

Ich kann den Bildschirm mit folgenden Funktionen ausschalten:

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);

Ich konnte den Bildschirm mit der Methode wl.release () nicht ausschalten.

Display-Test einschalten

Meine erste Vermutung wie folgt funktioniert nicht. Nichts passiert, Bildschirm bleibt ausgeschaltet.

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = -1f;
getWindow().setAttributes(params);

Ich habe dann auch versucht, Wakelocks zu verwenden, ohne Erfolg.

PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "tag");
wl.acquire();

Schließlich habe ich Folgendes versucht, ohne Ergebnis.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

Alles in allem wird bei keiner dieser Methoden ein Fehler in der Konsole angezeigt. Mein Testtext "Bildschirm sollte eingeschaltet sein" wird auf dem Bildschirm angezeigt, wenn ich das Gerät mit dem Netzschalter einschalte. Dies zeigt, dass der Code ausgeführt werden sollte. Bitte antworten Sie nur, wenn Sie den Code getestet haben. Es scheint, dass viele der Funktionen wie z. B. params.screenBrightness = -1nicht so funktionieren, wie sie laut SDK sollten.

thegreyspot
quelle
1
Ihre Methode zum Ausschalten des Bildschirms hat bei mir nicht funktioniert. Sie setzen das Flag, um den Bildschirm die ganze Zeit eingeschaltet zu halten, wodurch der Strom verbraucht wird.
Kristy Welsh
Hast du das jemals herausgefunden? Es gibt einige Apps im PlayStore, die dies vorschlagen. Versuchte dieses und es funktioniert, aber es fragt nach Geräteverwaltung. play.google.com/store/apps/…
George
Hast du etwas in diesem Problem erreicht? !!
Muhammed Refaat

Antworten:

69

Ich gehe davon aus, dass Sie nur möchten, dass dies wirksam wird, während Ihre Anwendung im Vordergrund steht.

Dieser Code:

params.flags |= LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0;
getWindow().setAttributes(params);

Schaltet den Bildschirm nicht im herkömmlichen Sinne aus. Dadurch wird der Bildschirm so dunkel wie möglich. In der Standardplattform gibt es eine Grenze, wie dunkel es sein kann; Wenn Ihr Gerät tatsächlich zulässt, dass der Bildschirm vollständig ausgeschaltet wird, ist dies eine Besonderheit der Implementierung dieses Geräts und kein Verhalten, auf das Sie sich geräteübergreifend verlassen können.

Wenn Sie dies in Verbindung mit FLAG_KEEP_SCREEN_ON verwenden, bedeutet dies, dass Sie niemals zulassen, dass der Bildschirm ausgeht (und somit das Gerät in den Energiesparmodus wechselt), selbst wenn Sie mit dem jeweiligen Gerät die Bildschirmhelligkeit auf "Aus" einstellen können. Denken Sie sehr stark daran. Sie verbrauchen viel mehr Strom als wenn der Bildschirm wirklich ausgeschaltet wäre.

Um den Bildschirm wieder auf normale Helligkeit zu bringen, sollten Sie nur den Helligkeitswert einstellen:

WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = -1;
getWindow().setAttributes(params);

Ich kann nicht erklären, warum dies den zuvor eingestellten Wert 0 nicht ersetzen würde. Als Test können Sie versuchen, eine erzwungene volle Helligkeit zu verwenden, um diese spezifische Helligkeit zu erzwingen:

WindowManager.LayoutParams params = getWindow().getAttributes();
params.screenBrightness = 1;
getWindow().setAttributes(params);

Das funktioniert definitiv. In den Google Books-Apps können Sie beispielsweise die Bildschirmhelligkeit so einstellen, dass sie während der Verwendung eines Buches gedimmt wird, und beim Ausschalten zur normalen Helligkeit zurückkehren.

Um das Debuggen zu erleichtern, können Sie "adb shell dumpsys window" verwenden, um den aktuellen Status Ihres Fensters anzuzeigen. In den Daten für Ihr Fenster werden die aktuellen LayoutParams angezeigt, die dafür festgelegt wurden. Stellen Sie sicher, dass der Wert, von dem Sie denken, dass er tatsächlich vorhanden ist.

Auch hier ist FLAG_KEEP_SCREEN_ON ein separates Konzept. es und die Helligkeit haben keinen direkten Einfluss aufeinander. (Und es gibt keinen Grund, das Flag beim Rückgängigmachen der Helligkeit erneut zu setzen, wenn Sie es bereits gesetzt haben, als Sie die Helligkeit auf 0 gesetzt haben. Das Flag bleibt gesetzt, bis Sie es ändern.)

Hackbod
quelle
8
Gibt es eine bessere Möglichkeit, den Bildschirm auszuschalten?
Akash
Wie @hackbod oben angegeben hat, ist "params.screenBrightness = 0;" schaltet den Bildschirm nicht vollständig aus; Stattdessen wird der Bildschirm so dunkel wie möglich. Und "params.screenBrightness = -1;" Schaltet den Bildschirm auf die vorherige Helligkeitsstufe zurück. Es gibt jedoch Fälle, in denen wir den Bildschirm vollständig ausschalten müssen. Es kann andere Methoden geben ...
Jonathanzh
6
Was wären diese anderen Methoden, die den Bildschirm tatsächlich ausschalten, anstatt nur die minimale Helligkeit einzustellen, die möglicherweise funktioniert oder nicht?
Michael
37

Ich hatte diese Methode geschrieben, um den Bildschirm nach der Bildschirmsperre einzuschalten. Es funktioniert perfekt für mich. Versuch es-

    private void unlockScreen() {
        Window window = this.getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    }

Und rufen Sie diese Methode von auf onResume().

Rajkiran
quelle
1
Nicht nützlich, wenn Sie den Bildschirm einschalten möchten, wenn Sie die Aktivität beenden möchten.
AndroidDev
7
Nun Leute, ich werde vorschlagen, meine Methode nicht zu verwenden, da dies bei Micromax Canvas2 + bei mir nicht funktioniert hat. Verwenden Sie stattdessen diesen Link .
Rajkiran
28

Ich würde dieses vorschlagen:

PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
wl.acquire();

Das Flag ACQUIRE_CAUSES_WAKEUP wird folgendermaßen erklärt:

Normale Nachlaufsperren schalten die Beleuchtung nicht ein. Stattdessen bleibt die Beleuchtung nach dem Einschalten eingeschaltet (z. B. aufgrund von Benutzeraktivitäten). Dieses Flag erzwingt das sofortige Einschalten des Bildschirms und / oder der Tastatur, wenn das WakeLock erworben wird. Eine typische Verwendung wären Benachrichtigungen, die für den Benutzer wichtig sind, um sie sofort zu sehen.

Stellen Sie außerdem sicher, dass Sie über die folgende Berechtigung in der Datei AndroidManifewst.xml verfügen:

<uses-permission android:name="android.permission.WAKE_LOCK" />
Ramdroid
quelle
3
Leider ist das Flag SCREEN_BRIGHT_WAKE_LOCK veraltet.
Camille Sévigny
20

Hallo, ich hoffe das wird helfen:

 private PowerManager mPowerManager;
 private PowerManager.WakeLock mWakeLock;

 public void turnOnScreen(){
     // turn on screen
     Log.v("ProximityActivity", "ON!");
     mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "tag");
     mWakeLock.acquire();
}

 @TargetApi(21) //Suppress lint error for PROXIMITY_SCREEN_OFF_WAKE_LOCK
 public void turnOffScreen(){
     // turn off screen
     Log.v("ProximityActivity", "OFF!");
     mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "tag");
     mWakeLock.acquire();
}
mangu23
quelle
Wie schalte ich den Bildschirm aus, ohne den Näherungssensor einzubeziehen?
Michael
Hallo @Michael, Sie verwenden einfach nur die Funktion public void turnOffScreen ()
mangu23
3
Ja, aber es scheint, dass diese Funktion verwendet, PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKdie den Bildschirm nur ausschaltet, wenn sich der Näherungssensor im Zustand "Nah" befindet.
Michael
Ahh okay, ich verstehe, Sie können dies stattdessen verwenden PowerManager.SCREEN_DIM_WAKE_LOCK
mangu23
1
Problem - Sobald ich die PROXIMITY_SCREEN_OFF_WAKE_LOCKWartesperre loslasse, wird der Bildschirm wieder eingeschaltet. Wie verhindere ich das?
Michael
7
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

// Benutzermanifestdatei

Pir Fahim Shah
quelle
2
Dies sollte die richtige Antwort sein. Ich benutze Android 5 und dies ist das einzige, was tatsächlich funktioniert. Der einzige Nebeneffekt ist, dass SCREEN_BRIGHT_WAKE_LOCK veraltet ist und ich keinen Drop-In-Ersatz sehe. Jemand?
HammerNL
Es gibt kein Problem, Ihre Antwort ist perfekt verwendbar. Wie gesagt: "Es ist die einzige Antwort, die tatsächlich funktioniert"
HammerNL
@HammerNL Was ist der Unterschied zwischen dieser Antwort und der Antwort von Ramdroid?
Fehler passieren
@ BugsHappen Ramdroids man ist ausgefeilter :) Aber ja, es ist das gleiche. Ich weiß nicht, warum Pir Fahim Shah diese Antwort gepostet hat oder warum ich Ramdroids zu diesem Zeitpunkt nicht gesehen habe.
HammerNL
6

Sind Sie sicher, dass Sie die richtige Berechtigung in Ihrer Manifest-Datei angefordert haben?

<uses-permission android:name="android.permission.WAKE_LOCK" />

Mit der AlarmManager 1- Klasse können Sie eine Absicht auslösen , die Ihre Aktivität startet und die Wecksperre erwirbt. Dadurch wird der Bildschirm eingeschaltet und eingeschaltet. Durch Loslassen des Wakelocks kann das Gerät selbstständig einschlafen.

Sie können auch einen Blick auf die Verwendung des PowerManager werfen, um das Gerät in den Energiesparmodus zu versetzen: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

Zambotron
quelle
1
Danke für die Antwort. Ja, ich bin sicher. Es ist in meinem Manifest und es gibt keine Debug-Fehler. AlarmManager hilft mir nicht, wenn ich Sensoren verwende, um den Bildschirm einzuschalten. Ich hatte nicht viel Glück mit goToSleep, aber das hilft mir immer noch nicht beim Einschalten des Bildschirms. Ich bin derzeit in der Lage, den Bildschirm auszuschalten
thegreyspot
5

Der beste Weg, dies zu tun (mit gerooteten Geräten):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    .
    .
    .

    int flags = WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
    getWindow().addFlags(flags); // this is how your app will wake up the screen
    //you will call this activity later

   .
   .
   .
}

Jetzt haben wir diese zwei Funktionen:

private void turnOffScreen(){

  try{
     Class c = Class.forName("android.os.PowerManager");
     PowerManager  mPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
     for(Method m : c.getDeclaredMethods()){
        if(m.getName().equals("goToSleep")){
          m.setAccessible(true);
          if(m.getParameterTypes().length == 1){
            m.invoke(mPowerManager,SystemClock.uptimeMillis()-2);
          }
        }
     } 
  } catch (Exception e){
  }
}

Und das:

public void turnOnScreen(){
  Intent i = new Intent(this,YOURACTIVITYWITHFLAGS.class);
  startActivity(i);
}

Entschuldigung für mein schlechtes Englisch.

Rodrigo Gontijo
quelle
Hallo, Rodrigo Gontijo Warum müssen wir Gerät pl rooten. Sag mir?
Kinjal
@Kinjal, da Sie die Funktion ("goToSleep") aufrufen müssen und für diese Funktion eine spezielle Berechtigung erforderlich ist, die nur System-Apps erteilt wird: <Verwendungsberechtigung android: name = "android.permission.DEVICE_POWER" />
Rodrigo Gontijo
ok danke und bitte geben Sie einen Link oder einen Schritt an, wie Sie das Gerät rooten, wenn möglich. Danke im Voraus.
Kinjal
4

Hier ist ein erfolgreiches Beispiel für eine Implementierung derselben Funktion auf einem Gerät, das niedrigere Bildschirmhelligkeitswerte unterstützt (ich habe sie auf einem Allwinner Chinese 7 "-Tablet mit API15 getestet).

WindowManager.LayoutParams params = this.getWindow().getAttributes();

/** Turn off: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO Store original brightness value
params.screenBrightness = 0.1f;
this.getWindow().setAttributes(params);

/** Turn on: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
//TODO restoring from original value
params.screenBrightness = 0.9f;
this.getWindow().setAttributes(params);

Wenn jemand anderes dies ausprobiert, kommentieren Sie bitte unten, ob es funktioniert hat / nicht funktioniert hat und das Gerät, die Android-API.

ılǝ
quelle
2
Auf meinem Gerät, Nexus 7, funktioniert dies nicht gut, der Bildschirm ist immer noch eingeschaltet, nur etwas dunkler, aber nicht vollständig schwarz.
JackWM
Dann sollte diese Implementierung sicherlich nicht für eine öffentliche Version verwendet werden, obwohl sie möglicherweise einer Integration mit einem bestimmten Gerät dient. Ich werde den Beitrag behalten, da er jemandem für später helfen könnte.
ılǝ
3

So behalten Sie den Bildschirm bei:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Zurück zum Standardmodus des Bildschirms: Deaktivieren Sie einfach das Flag FLAG_KEEP_SCREEN_ON

getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Marco Aurelio Silva
quelle
3

Dies wird auf Marshmallow gearbeitet

private final String TAG = "OnOffScreen";
private PowerManager _powerManager;
private PowerManager.WakeLock _screenOffWakeLock;

public void turnOnScreen() {
    if (_screenOffWakeLock != null) {
        _screenOffWakeLock.release();
    }
}

public void turnOffScreen() {
    try {
        _powerManager = (PowerManager) this.getSystemService(POWER_SERVICE);
        if (_powerManager != null) {
            _screenOffWakeLock = _powerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
            if (_screenOffWakeLock != null) {
                _screenOffWakeLock.acquire();
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
mbsysd
quelle
Es wäre großartig, wenn Sie erklären würden, warum Ihre Antwort funktioniert, was SO-Mitgliedern hilft, besser zu verstehen.
dkb
funktioniert nicht so gut aus dem Bildschirm drehen ... , wenn der Näherungssensor aus der Nähe geht zu weit, kommt der Bildschirm wieder auf ... und wenn ich vor , dass die Wake Sperre wieder freigeben, es noch kommt auf sofort !
Michael
2

In Bezug auf die Android-Dokumentation kann dies mithilfe der folgenden Codezeile erreicht werden:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Ich habe dies in meiner onCreateMethode hinzugefügt und es funktioniert gut.

Unter dem Link finden Sie verschiedene Möglichkeiten, dies zu erreichen, sowie allgemeine Erklärungen.

Link zur Dokumentation: https://developer.android.com/training/scheduling/wakelock.html

Maytham-ɯɐɥʇʎɐɯ
quelle
2

Wenn Ihre App eine System-App ist, können Sie mit PowerManager.goToSleep () den Bildschirm ausschalten. Sie benötigen eine spezielle Berechtigung

Bevor Sie goToSleep () verwenden, müssen Sie Reflection wie folgt verwenden:

public static void goToSleep(Context context) {
    PowerManager powerManager= (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    try {
        powerManager.getClass().getMethod("goToSleep", new Class[]{long.class}).invoke(powerManager, SystemClock.uptimeMillis());
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
}

Jetzt können Sie mit goToSleep () den Bildschirm ausschalten.

Dies geschieht, wenn die Ein- / Aus-Taste gedrückt wird, um den Bildschirm auszuschalten.

Rickon Gao
quelle
2

Einfach hinzufügen

android:keepScreenOn="true" 

oder anrufen

setKeepScreenOn(true) 

in der übergeordneten Ansicht.

Mani
quelle
1

Ich hätte keine Hoffnung, den Bildschirm in der Aktivität zu "wecken". Wenn der Bildschirm ausgeschaltet ist, befindet sich die Aktivität wahrscheinlich in einem angehaltenen Zustand und sollte keinen Code ausführen.

Beim Aufwachen tritt das Problem mit dem Sperrbildschirm auf. Ich weiß nicht, wie eine App den Sperrbildschirm automatisch umgehen kann.

Sie sollten in Betracht ziehen, Ihre Hintergrundaufgaben in einem Dienst auszuführen und dann mithilfe des Benachrichtigungsmanagers eine Benachrichtigung zu senden, wenn etwas erkannt wird. Die Benachrichtigung sollte eine Art Gerätealarm enthalten (Bildschirmweck, Benachrichtigungssymbol, Benachrichtigungs-LED usw.). Wenn Sie auf die Benachrichtigung klicken, kann die Absicht gestartet werden, Ihre Aktivität zu starten.

Sie könnten auch versuchen, die Aktivität direkt vom Dienst aus zu starten, aber ich weiß wirklich nicht, ob dadurch der Bildschirm eingeschaltet oder der Sperrbildschirm umgangen wird.

HaMMeReD
quelle
Vielen Dank für die Antwort. Ich habe einen Vibrationscode eingegeben. Wenn der Bildschirm ausgeschaltet ist und ich einen meiner Sensoren aktiviere, vibriert er. Der Code läuft also definitiv. Der Sperrbildschirm ist keine große Sache, ich benutze nur Schlüsselschutz.
Thegreyspot
Selbst wenn der Code ausgeführt wird, liegt er außerhalb des Lebenszyklus. Sie können Aktivitäten außerhalb des Bildschirms nicht vertrauen. Denken Sie an Spiel-Downloader, die meisten sind in der Aktivität geschrieben und Sie können sie für etwa 30 Sekunden bis einige Minuten verlassen. Sie werden weiterhin heruntergeladen, brechen jedoch normalerweise ab, da das Betriebssystem die Aktivität basierend auf Ihren Nutzungsmustern beendet.
HaMMeReD
1

Gemäß Android API 28 und höher müssen Sie die folgenden Schritte ausführen, um den Bildschirm einzuschalten

setShowWhenLocked(true); 
setTurnScreenOn(true); 
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
Axesh Ajmera
quelle