Android: comment activer et désactiver l'écran par programmation?

98

Avant de marquer ce message comme "duplicata", j'écris ce message car aucun autre message ne contient la solution au problème.

J'essaie d'éteindre l'appareil, puis après quelques minutes ou un changement de capteur, rallumez-le.

Désactiver les tests d'affichage

Je peux éteindre l'écran en utilisant:

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

Je n'ai pas pu éteindre l'écran en utilisant la méthode wl.release ().

Activer le test d'affichage

Ma première hypothèse, comme suit, ne fonctionne pas. Rien ne se passe, l'écran reste éteint.

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

J'ai également essayé d'utiliser des wakelocks, sans succès.

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

Enfin, j'ai essayé ce qui suit, sans résultat.

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

Dans l'ensemble, je n'obtiens aucune sorte d'erreur dans la console pour aucune de ces méthodes. Mon texte de test «L'écran doit être allumé» s'affiche à l'écran lorsque j'allume l'appareil à l'aide du bouton d'alimentation. Cela montre que le code aurait dû s'exécuter. Veuillez ne répondre que si vous avez testé le code, il semble que de nombreuses fonctions telles que params.screenBrightness = -1, ne fonctionnent pas comme elles le devraient selon le sdk.

thegreyspot
la source
1
Votre méthode pour éteindre l'écran n'a pas fonctionné pour moi. Vous définissez le drapeau pour garder l'écran allumé tout le temps, ce qui épuise l'énergie.
Kristy Welsh
Avez-vous déjà compris cela? Il y a quelques applications sur PlayStore qui suggèrent de le faire. J'ai essayé celui-ci et cela fonctionne mais il demande une administration de périphérique. play.google.com/store/apps/…
George
avez-vous atteint quelque chose dans ce problème? !!
Muhammed Refaat

Réponses:

69

Je vais supposer que vous voulez que cela ne soit en vigueur que lorsque votre application est au premier plan.

Ce code:

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

N'éteint pas l'écran au sens traditionnel du terme. Cela rend l'écran aussi sombre que possible. Dans la plate-forme standard, la luminosité peut être limitée; si votre appareil permet en fait à l'écran de s'éteindre complètement, c'est une particularité de la mise en œuvre de cet appareil et non un comportement sur lequel vous pouvez compter sur tous les appareils.

En fait, l'utiliser en conjonction avec FLAG_KEEP_SCREEN_ON signifie que vous ne permettrez jamais à l'écran de s'éteindre (et donc à l'appareil de passer en mode basse consommation), même si l'appareil particulier vous permet de régler la luminosité de l'écran à son maximum. Gardez cela à l'esprit. Vous utiliserez beaucoup plus d'énergie que si l'écran était vraiment éteint.

Maintenant, pour ramener l'écran à la luminosité normale, il suffit de régler la valeur de luminosité:

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

Je ne peux pas expliquer pourquoi cela ne remplacerait pas la valeur 0 que vous aviez précédemment définie. À titre de test, vous pouvez essayer d'y mettre une luminosité totale forcée pour forcer cette luminosité spécifique:

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

Cela fonctionne vraiment. Par exemple, les applications Livres de Google l'utilisent pour vous permettre de régler la luminosité de l'écran sur la luminosité lorsque vous utilisez un livre, puis de revenir à la luminosité normale lorsque vous la désactivez.

Pour aider au débogage, vous pouvez utiliser "adb shell dumpsys window" pour voir l'état actuel de votre fenêtre. Dans les données de votre fenêtre, il vous indiquera les LayoutParams actuels qui ont été définis pour elle. Assurez-vous que la valeur que vous pensez est bien là.

Et encore une fois, FLAG_KEEP_SCREEN_ON est un concept distinct; elle et la luminosité n'ont aucun impact direct l'une sur l'autre. (Et il n'y aurait aucune raison de redéfinir l'indicateur lors de l'annulation de la luminosité, si vous l'aviez déjà défini lors de la mise à 0. L'indicateur restera activé jusqu'à ce que vous le changiez.)

hackbod
la source
8
Existe-t-il un meilleur moyen d'éteindre les écrans?
akash
Comme @hackbod l'a indiqué ci-dessus, "params.screenBrightness = 0;" n'éteint pas complètement l'écran; au lieu de cela, cela rend l'écran aussi sombre que possible. Et "params.screenBrightness = -1;" ramène l'écran à son niveau de luminosité précédent. Cependant, il y a des cas où nous devons éteindre complètement l'écran. Il peut y avoir d'autres méthodes ...
jonathanzh
6
Quelles seraient ces autres méthodes qui éteignent réellement l'écran plutôt que de simplement définir une luminosité minimale qui peut ou non fonctionner?
Michael
37

J'avais écrit cette méthode pour allumer l'écran après le verrouillage de l'écran. Cela fonctionne parfaitement pour moi. Essayez-le

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

Et appelez cette méthode à partir de onResume().

Rajkiran
la source
1
Pas utile si vous prévoyez d'allumer l'écran lorsque vous souhaitez mettre fin à l'activité.
AndroidDev
7
Eh bien les gens, je suggérerai de ne pas utiliser ma méthode car cela n'a pas fonctionné pour moi sur Micromax Canvas2 +. Utilisez plutôt ce lien .
Rajkiran
28

Je suggérerais celui-ci:

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

Le drapeau ACQUIRE_CAUSES_WAKEUP est expliqué comme ça:

Les verrous de réveil normaux n'activent pas réellement l'éclairage. Au lieu de cela, ils font que l'éclairage reste allumé une fois qu'il est allumé (par exemple à cause de l'activité de l'utilisateur). Cet indicateur forcera l'écran et / ou le clavier à s'allumer immédiatement, lorsque le WakeLock sera acquis. Une utilisation typique serait pour les notifications qui sont importantes pour l'utilisateur à voir immédiatement.

Assurez-vous également que vous disposez de l'autorisation suivante dans le fichier AndroidManifewst.xml:

<uses-permission android:name="android.permission.WAKE_LOCK" />
ramdroid
la source
3
Malheureusement, l'indicateur SCREEN_BRIGHT_WAKE_LOCK est obsolète.
Camille Sévigny
20

Salut j'espère que cela aidera:

 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
la source
Comment éteindre l'écran sans impliquer le capteur de proximité?
Michael
Salut @Michael, vous utilisez simplement la fonction publique void turnOffScreen () uniquement
mangu23
3
Oui, mais il semble que cette fonction utilise PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCKce qui n'éteint l'écran que lorsque le capteur de proximité est à l'état "proche".
Michael
Ahh ok je comprends, vous pouvez utiliser ceci à la place PowerManager.SCREEN_DIM_WAKE_LOCK
mangu23
1
Problème - dès que je relâche le PROXIMITY_SCREEN_OFF_WAKE_LOCKverrou d'attente, l'écran se rallume. Comment éviter cela?
Michael
7
     WakeLock screenLock =    ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
    PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
    screenLock.acquire();

  //later
  screenLock.release();

// Fichier manifeste de l'utilisateur

Pir Fahim Shah
la source
2
Cela devrait être la bonne réponse. J'utilise Android 5 et c'est la seule chose qui fonctionne réellement. La seule remarque est que SCREEN_BRIGHT_WAKE_LOCK est obsolète, et je ne vois pas de remplacement instantané. N'importe qui?
HammerNL
Il n'y a pas de problème, votre réponse est parfaitement exploitable. Comme je l'ai dit: "c'est la seule réponse qui fonctionne réellement"
HammerNL
@HammerNL Quelle est la différence entre cette réponse et la réponse fournie par ramdroid?
Bugs Happen
@BugsHappen Ramdroids un est plus élaboré :) Mais oui, c'est pareil. Je ne sais pas pourquoi Pir Fahim Shah a posté cette réponse, ou pourquoi je n'en ai pas vu un Ramdroids à l'époque.
HammerNL
6

Êtes-vous sûr d'avoir demandé l'autorisation appropriée dans votre fichier manifeste?

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

Vous pouvez utiliser la classe AlarmManager 1 pour déclencher une intention qui démarre votre activité et acquiert le verrou de réveil. Cela allumera l'écran et le gardera allumé. Le relâchement du wakelock permettra à l'appareil de s'endormir tout seul.

Vous pouvez également jeter un œil à l'utilisation du PowerManager pour mettre l'appareil en veille: http://developer.android.com/reference/android/os/PowerManager.html#goToSleep(long)

Zambotron
la source
1
Merci pour la réponse. Oui je suis sûr. C'est dans mon manifeste et il n'y a aucune erreur de débogage. AlarmManager ne m'aidera pas lorsque j'utilise des capteurs pour allumer l'écran. Je n'ai pas eu beaucoup de chance avec goToSleep, mais ça ne m'aide toujours pas à allumer l'écran. Je suis actuellement en mesure de faire sonner l'écran
thegreyspot
5

La meilleure façon de le faire (en utilisant des appareils rootés):

@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

   .
   .
   .
}

Maintenant, nous avons ces deux fonctions:

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

Et ça:

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

Désolé pour mon mauvais anglais.

Rodrigo Gontijo
la source
Bonjour, Rodrigo Gontijo Pourquoi nous devons rooter le périphérique pl. dîtes-moi?
Kinjal
@Kinjal car vous devez appeler la fonction ("goToSleep") et cette fonction nécessite une autorisation spéciale, accordée uniquement aux applications système: <uses-permission android: name = "android.permission.DEVICE_POWER" />
Rodrigo Gontijo
ok merci et s'il vous plaît fournir un lien ou une étape comment rooter le périphérique si possible. Merci d'avance.
Kinjal
4

Voici un exemple réussi d'une implémentation de la même chose, sur un appareil prenant en charge des valeurs de luminosité d'écran inférieures (j'ai testé sur une tablette Allwinner Chinese 7 "exécutant 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 quelqu'un d'autre essaie cela, veuillez commenter ci-dessous si cela a fonctionné / n'a pas fonctionné et l'appareil, l'API Android.

ılǝ
la source
2
Sur mon appareil, le Nexus 7, cela ne fonctionne pas bien, l'écran est toujours allumé, juste un peu plus sombre, mais pas complètement noir.
JackWM
Cette implémentation ne doit sûrement pas être utilisée pour une version publique, bien qu'elle puisse servir une intégration avec un appareil spécifique. Je garderai le message car cela pourrait aider quelqu'un pour plus tard.
ılǝ
3

Pour garder l'écran allumé:

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

Retour au mode par défaut de l'écran: effacez simplement l'indicateur FLAG_KEEP_SCREEN_ON

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

Ceci est travaillé sur 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
la source
Ce serait formidable si vous expliquiez pourquoi votre réponse fonctionne, ce qui aidera le membre SO à mieux comprendre.
dkb
éteindre l'écran ne fonctionne pas si bien ... lorsque le capteur de proximité passe de près à loin, l'écran se rallume ... et si je relâche le verrou de réveil avant cela, il s'allume toujours immédiatement !
Michael
2

En ce qui concerne la documentation Android, cela peut être réalisé en utilisant la ligne de code suivante:

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

J'ai ajouté ceci dans ma onCreateméthode et cela fonctionne très bien.

Sur le lien, vous trouverez différentes façons d'y parvenir ainsi que des explications générales.

Lien vers la documentation: https://developer.android.com/training/scheduling/wakelock.html

maytham-ɯɐɥʇʎɐɯ
la source
2

Si votre application est une application système, vous pouvez utiliser PowerManager.goToSleep () pour désactiver l'écran, vous avez besoin d'une autorisation spéciale

avant d'utiliser goToSleep (), vous devez utiliser la réflexion comme:

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

Maintenant, vous pouvez utiliser goToSleep () pour éteindre l'écran.

C'est ce qui se produit lorsque vous appuyez sur la touche marche / arrêt pour éteindre l'écran.

Rickon Gao
la source
2

Ajoutez simplement

android:keepScreenOn="true" 

ou appeler

setKeepScreenOn(true) 

sur la vue parent.

mani
la source
1

Je n'aurais pas l'espoir de "réveiller l'écran" dans l'activité. Si l'écran est éteint, l'activité est probablement en pause et ne doit pas exécuter de code.

Au réveil, il y a le problème de l'écran de verrouillage. Je ne sais pas comment une application peut automatiquement contourner l'écran de verrouillage.

Vous devriez envisager d'exécuter vos tâches d'arrière-plan dans un service, puis d'utiliser le gestionnaire de notifications pour envoyer une notification lorsque tout ce qui est détecté. La notification doit fournir une sorte d'alerte de l'appareil (réveil de l'écran, icône de notification, voyant de notification, etc.). En cliquant sur la notification, il peut lancer l'intention de démarrer votre activité.

Vous pouvez également essayer de démarrer l'activité directement à partir du service, mais je ne sais vraiment pas si cela activera l'écran ou contournera l'écran de verrouillage.

HAMMÉRED
la source
Merci pour la réponse, j'ai mis du code de vibration, et quand j'ai l'écran éteint et que j'active l'un de mes capteurs, il vibre. Donc, le code est définitivement en cours d'exécution. Le lockscreen n'est pas un gros problème, j'utilise juste le keyguard.
thegreyspot
Même si le code s'exécute, il est en dehors du cycle de vie. Vous ne pouvez pas faire confiance aux activités qui ne sont pas affichées. Pensez aux téléchargeurs de jeux, la plupart sont écrits dans l'activité et vous pouvez partir pendant peut-être 30 secondes à quelques minutes et ils continueront à télécharger, mais ils se cassent généralement parce que le système d'exploitation tue l'activité en fonction de vos habitudes d'utilisation.
HAMMeReD
1

Conformément à l'API Android 28 et au-dessus, vous devez effectuer les opérations suivantes pour allumer l'écran

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