Android: ¿Cómo encender y apagar la pantalla mediante programación?

98

Antes de marcar esta publicación como "duplicada", estoy escribiendo esta publicación porque ninguna otra publicación contiene la solución al problema.

Estoy tratando de apagar el dispositivo, luego, después de unos minutos o de un cambio de sensor, vuelva a encenderlo.

Desactivar las pruebas de pantalla

Puedo apagar la pantalla usando:

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

No he podido apagar la pantalla con el método wl.release ().

Activar prueba de pantalla

Mi primera suposición, como sigue, no funciona. No pasa nada, la pantalla permanece apagada.

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

Luego también intenté usar wakelocks, sin éxito.

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

Finalmente probé lo siguiente, sin resultado.

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

Con todo, no obtengo ningún tipo de error en la consola para ninguno de estos métodos. Mi texto de prueba "La pantalla debería estar encendida" aparece en la pantalla cuando enciendo el dispositivo con el botón de encendido. Esto muestra que el código debería haberse ejecutado. Por favor, solo responda si ha probado el código, parece que muchas de las funciones como params.screenBrightness = -1, no funcionan como deberían según el sdk.

thegreyspot
fuente
1
Tu método para apagar la pantalla no me funcionó. Establece la bandera para mantener la pantalla encendida todo el tiempo, lo que consumirá energía.
Kristy Welsh
¿Alguna vez resolviste esto? Hay algunas aplicaciones en PlayStore que sugieren que lo hagan. Probé este y funciona, pero solicita Administración de dispositivos. play.google.com/store/apps/…
George
¿Alcanzaste algo en este problema? !!
Muhammed Refaat

Respuestas:

69

Asumiré que solo desea que esto esté en vigor mientras su aplicación esté en primer plano.

Este código:

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

No apaga la pantalla en el sentido tradicional. Hace que la pantalla sea lo más tenue posible. En la plataforma estándar hay un límite en cuanto a lo tenue que puede ser; si su dispositivo realmente permite que la pantalla se apague por completo, entonces es una peculiaridad de la implementación de ese dispositivo y no un comportamiento con el que pueda contar en todos los dispositivos.

De hecho, usar esto junto con FLAG_KEEP_SCREEN_ON significa que nunca permitirá que la pantalla se apague (y, por lo tanto, que el dispositivo entre en modo de bajo consumo) incluso si el dispositivo en particular le permite configurar el brillo de la pantalla al máximo. Tenga esto muy en cuenta. Utilizará mucha más energía de la que utilizaría si la pantalla estuviera realmente apagada.

Ahora, para volver la pantalla al brillo normal, solo debe configurar el valor de brillo:

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

No puedo explicar por qué esto no reemplazaría el valor 0 que había establecido anteriormente. Como prueba, puede intentar poner un brillo completo forzado allí para forzar ese brillo específico:

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

Esto definitivamente funciona. Por ejemplo, las aplicaciones de Google Books usan esto para permitirle configurar el brillo de la pantalla para que se atenúe mientras usa un libro y luego volver al brillo normal al apagarlo.

Para ayudar a depurar, puede usar "adb shell dumpsys window" para ver el estado actual de su ventana. En los datos de su ventana, le indicará los LayoutParams actuales que se han configurado para ella. Asegúrese de que el valor que cree que realmente está ahí.

Y nuevamente, FLAG_KEEP_SCREEN_ON es un concepto separado; él y el brillo no tienen un impacto directo entre sí. (Y no habría razón para volver a establecer la bandera al deshacer el brillo, si ya la había configurado al poner el brillo a 0. La bandera permanecerá configurada hasta que la cambie).

hackbod
fuente
8
¿Existe una mejor manera de apagar la pantalla?
Akash
Como @hackbod ha dicho anteriormente, "params.screenBrightness = 0;" no apaga la pantalla por completo; en cambio, hace que la pantalla sea lo más tenue posible. Y "params.screenBrightness = -1;" devuelve la pantalla a su nivel de brillo anterior. Sin embargo, hay casos en los que necesitamos apagar la pantalla por completo. Puede haber otros métodos ...
Jonathanzh
6
¿Cuáles serían esos otros métodos que realmente apagan la pantalla en lugar de simplemente establecer el brillo mínimo que puede o no funcionar?
Michael
37

Escribí este método para encender la pantalla después del bloqueo de pantalla. Funciona perfectamente para mí. Intentalo-

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

Y llame a este método desde onResume().

Rajkiran
fuente
1
No es útil si planea encender la pantalla cuando desea terminar la actividad.
AndroidDev
7
Bueno, les sugeriré que no utilicen mi método, ya que esto no me funcionó en Micromax Canvas2 +. Utilice este enlace en su lugar.
Rajkiran
28

Sugeriría este:

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

La bandera ACQUIRE_CAUSES_WAKEUP se explica así:

Los wake locks normales no encienden la iluminación. En cambio, hacen que la iluminación permanezca encendida una vez que se enciende (por ejemplo, debido a la actividad del usuario). Esta bandera forzará a la pantalla y / o al teclado a encenderse inmediatamente, cuando se adquiera WakeLock. Un uso típico sería para notificaciones que son importantes para que el usuario las vea de inmediato.

Además, asegúrese de tener el siguiente permiso en el archivo AndroidManifewst.xml:

<uses-permission android:name="android.permission.WAKE_LOCK" />
ramdroid
fuente
3
Desafortunadamente, la bandera SCREEN_BRIGHT_WAKE_LOCK ha quedado obsoleta.
Camille Sévigny
20

Hola, espero que esto te ayude:

 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
fuente
¿Cómo apagar la pantalla sin involucrar al sensor de proximidad?
Michael
Hola @Michael, simplemente usa la función public void turnOffScreen () solamente
mangu23
3
Sí, pero parece que utiliza esta función PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKque solo apaga la pantalla cuando el sensor de proximidad está en el estado "cerca".
Michael
Ahh está bien, entiendo, puede usar esto en su lugar
PowerManager.SCREEN_DIM_WAKE_LOCK
1
Problema: tan pronto como suelto el PROXIMITY_SCREEN_OFF_WAKE_LOCKbloqueo de espera, la pantalla vuelve a encenderse. ¿Cómo puedo prevenir esto?
Michael
7
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

// Archivo de manifiesto de usuario

Pir Fahim Shah
fuente
2
Esta debería ser la respuesta correcta. Estoy usando Android 5 y esto es lo único que realmente funciona. La única nota al margen es que SCREEN_BRIGHT_WAKE_LOCK está en desuso y no veo un reemplazo directo. ¿Nadie?
HammerNL
No hay problema, su respuesta es perfectamente utilizable. Como dije: "es la única respuesta que realmente funciona"
HammerNL
@HammerNL ¿cuál es la diferencia entre esta respuesta y la respuesta proporcionada por ramdroid?
Errores ocurren
@BugsHappen Ramdroids uno es más elaborado :) Pero sí, es lo mismo. No sé por qué Pir Fahim Shah publicó esta respuesta, o por qué no vi a Ramdroids uno en ese momento.
HammerNL
6

¿Está seguro de que solicitó el permiso adecuado en su archivo de manifiesto?

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

Puede usar la clase AlarmManager 1 para disparar una intención que inicia su actividad y adquiere el bloqueo de activación. Esto encenderá la pantalla y la mantendrá encendida. Liberar el wakelock permitirá que el dispositivo se duerma por sí solo.

También puede echar un vistazo al uso de PowerManager para configurar el dispositivo en suspensión: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(largo)

Zambotron
fuente
1
Gracias por la respuesta. Sí, estoy seguro. Está en mi manifiesto y no hay errores de depuración. AlarmManager no me ayudará cuando utilizo sensores para encender la pantalla. No he tenido mucha suerte con goToSleep, pero eso todavía no me ayuda a encender la pantalla. Actualmente puedo hacer que la pantalla se apague
thegreyspot
5

La mejor manera de hacerlo (usando dispositivos rooteados):

@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

   .
   .
   .
}

Ahora tenemos estas dos funciones:

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){
  }
}

Y esto:

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

Perdón por mi mal ingles.

Rodrigo Gontijo
fuente
Hola, Rodrigo Gontijo Por qué necesitamos rootear el dispositivo pl. ¿Dime?
Kinjal
@Kinjal porque necesitas invocar la función ("goToSleep") y esta función requiere un permiso especial, solo otorgado a las aplicaciones del sistema: <uses-allow android: name = "android.permission.DEVICE_POWER" />
Rodrigo Gontijo
ok gracias y por favor proporcione un enlace o paso cómo rootear el dispositivo si es posible. Gracias por adelantado.
Kinjal
4

Aquí hay un ejemplo exitoso de una implementación de lo mismo, en un dispositivo que admitía valores de brillo de pantalla más bajos (probé en una tableta Allwinner Chinese de 7 "con API15).

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

Si alguien más prueba esto, por favor comente a continuación si funcionó / ​​no funcionó y el dispositivo, la API de Android.

ılǝ
fuente
2
En mi dispositivo, nexus 7, esto no funciona bien, la pantalla sigue encendida, solo un poco más oscura, pero no completamente negra.
JackWM
Seguramente esta implementación no debería usarse para un lanzamiento público, aunque puede servir para una integración con un dispositivo específico. Me quedaré con la publicación, ya que podría ayudar a alguien más tarde.
2013
3

Para mantener la pantalla encendida:

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

Volver al modo predeterminado de pantalla: simplemente borre la bandera FLAG_KEEP_SCREEN_ON

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

Esto se trabajó en Marshmallow

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
fuente
Sería genial si explicara por qué su respuesta funciona, lo que ayudará a los miembros de SO a comprender mejor.
dkb
apagar la pantalla no funciona tan bien ... cuando el sensor de proximidad va de cerca a lejos, la pantalla vuelve a encenderse ... y si libero el bloqueo de activación antes de eso, ¡ todavía se enciende inmediatamente !
Michael
2

Con respecto a la documentación de Android, se puede lograr usando la siguiente línea de código:

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

He agregado esto en mi onCreatemétodo y funciona bien.

En el enlace encontrará diferentes formas de lograr esto y también una explicación general.

Enlace a la documentación: https://developer.android.com/training/scheduling/wakelock.html

maytham-ɯɐɥʇʎɐɯ
fuente
2

Si su aplicación es una aplicación del sistema, puede usar PowerManager.goToSleep () para apagar la pantalla, necesita un permiso especial

antes de usar goToSleep (), necesita usar la reflexión como:

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

Ahora, puede usar goToSleep () para apagar la pantalla.

Esto es lo que sucede cuando se presiona la tecla de encendido para apagar la pantalla.

Rickon Gao
fuente
2

Simplemente agregue

android:keepScreenOn="true" 

o llamar

setKeepScreenOn(true) 

en vista de los padres.

mani
fuente
1

No tendría la esperanza de "despertar la pantalla" en la actividad. Si la pantalla está apagada, la actividad probablemente esté en un estado de pausa y no debería estar ejecutando ningún código.

Al despertar, existe el problema de la pantalla de bloqueo. No sé cómo una aplicación puede omitir automáticamente la pantalla de bloqueo.

Debe considerar ejecutar sus tareas en segundo plano en un servicio y luego usar el administrador de notificaciones para enviar una notificación cuando se detecte algo. La notificación debe proporcionar algún tipo de alerta del dispositivo (activación de la pantalla, icono de notificación, led de notificación, etc.). Al hacer clic en la notificación, puede iniciar la intención de iniciar su actividad.

También puede intentar iniciar la actividad directamente desde el servicio, pero realmente no sé si eso encenderá la pantalla o evitará la pantalla de bloqueo.

HammeReD
fuente
Gracias por la respuesta, puse un código de vibración, y cuando tengo la pantalla apagada y activo uno de mis sensores, vibra. Entonces el código definitivamente se está ejecutando. La pantalla de bloqueo no es gran cosa, solo uso el bloqueo de teclas.
thegreyspot
Incluso si el código se ejecuta, está fuera del ciclo de vida. No puedes confiar en actividades que están fuera de la pantalla. Piense en los descargadores de juegos, la mayoría están escritos en la actividad y puede dejarlos durante unos 30 segundos o unos minutos y aún se descargarán, pero generalmente se rompen porque el sistema operativo elimina la actividad en función de sus patrones de uso.
HaMMeReD
1

Según la API de Android 28 y superior, debe hacer lo siguiente para encender la pantalla

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