Android – Réveil et délocking

Description de l’application: L’application est conçue comme un programme de sécurité pour un client spécifique (à ne pas déployer publiquement). Lorsque l’application n’a pas détecté de mouvement pendant un certain temps, l’application doit déclencher une alarme et se mettre au premier plan si elle se trouve en arrière-plan ou si l’appareil est en veille.

Le problème: Si l’appareil est endormi et verrouillé, nous devons nous réveiller et déverrouiller l’appareil. En utilisant diverses techniques disponibles ici sur SO et ailleurs, nous avons pu (partiellement) réveiller et déverrouiller le périphérique, mais celui-ci se comporte SEULEMENT lorsque le périphérique est physiquement connecté à un ordinateur. Si le périphérique est en mode débranché et que nous testons le wake-unlock, rien ne se passe; l’appareil semble restr endormi et l’application ne semble rien faire du tout (pas d’alarme).

J’ai utilisé cet article à propos de l’utilisation de PowerManager et de KeyguardManager , et de cette publication utilisant des drapeaux de fenêtre.

Voici le code actuellement utilisé pour réveiller le périphérique:

public void wakeDevice() { PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG"); wakeLock.acquire(); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); runOnUiThread(new Runnable(){ public void run(){ getWindow().addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } }); } 

D’après les commentaires et publications sur certaines des autres questions SO que j’ai vues / utilisées, il semble que le code PowerManager / KeyguardManager ait dû faire l’affaire. Encore une fois, comme je l’ai déjà dit, cela fonctionne techniquement lorsque l’appareil est connecté via USB à la machine de développement, mais ne fait absolument rien lorsque l’appareil est séparé.

Notez également qu’il s’agit de notre première application Android, et que nous sums parfaitement conscients que nous risquons de perdre tout ce que nous essayons de faire. Toutes les suggestions sont les bienvenues.

Donc, en bref, compte tenu du code ci-dessus, pourquoi l’appareil se comporte-t-il si différemment selon qu’il est branché, et que devons-nous changer pour réveiller et déverrouiller l’appareil comme décrit? Merci d’avance pour votre aide!

J’ai résolu le problème. La raison pour laquelle nous avons observé des comportements différents lorsque le périphérique était branché via USB était que le processeur de l’appareil ne s’endormait pas. Je suppose que cela est dû soit au réglage du mode de débogage, soit à la façon dont il se comporte lorsqu’il est connecté à un ordinateur, car la fonction d’économie d’énergie de la mise en veille du processeur ne serait pas pertinente. De toute évidence, lorsque le périphérique n’est pas branché, le processeur serait heureux de faire une sieste, et bien que nous ayons observé l’application au hasard (elle se réveillerait à des moments aléatoires), le timing serait incohérent. Je suppose en outre que c’est parce que les quelques cycles de CPU qui ont eu lieu sont alloués avec parcimonie et que notre application se verrait atsortingbuer très peu de cycles à des moments “aléatoires”.

Notre solution a donc consisté à saisir un verrou de réveil partiel lorsque le périphérique entre en arrière-plan (ce qui est fait dans la méthode onPause ) et à libérer le verrou dans la méthode onResume . Cela semble empêcher le processeur de dormir. Nous continuons à utiliser le locking complet du réveil et le locking du clavier pour réveiller le périphérique lorsque cela est nécessaire. L’utilisation du verrou de réveil partiel semble empêcher le processeur de dormir et l’appareil semble se réveiller correctement lorsque prévu. Voici notre code mis à jour, au cas où quelqu’un rencontrerait ce problème:

 // Called from onCreate protected void createWakeLocks(){ PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK"); partialWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Loneworker - PARTIAL WAKE LOCK"); } // Called implicitly when device is about to sleep or application is backgrounded protected void onPause(){ super.onPause(); partialWakeLock.acquire(); } // Called implicitly when device is about to wake up or foregrounded protected void onResume(){ super.onResume(); if(fullWakeLock.isHeld()){ fullWakeLock.release(); } if(partialWakeLock.isHeld()){ partialWakeLock.release(); } } // Called whenever we need to wake up the device public void wakeDevice() { fullWakeLock.acquire(); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); }