Android – Dispositivo de Despertar y Desbloquear

Descripción de la aplicación: la aplicación está pensada como un progtwig de seguridad para un cliente específico (no debe implementarse públicamente). Cuando la aplicación no ha detectado movimiento durante un cierto período de tiempo, la aplicación debe hacer sonar una alarma y ponerse en primer plano si está en el fondo o el dispositivo está dormido.

El problema: en caso de que el dispositivo esté dormido y bloqueado, debemos despertar y desbloquear el dispositivo. Usando varias técnicas que se encuentran aquí en SO y otros lugares, hemos sido capaces de (parcialmente) activar y desactivar el dispositivo, sin embargo, esto SOLO se comporta correctamente cuando el dispositivo está conectado físicamente a una computadora. Si el dispositivo está solo, desenchufado, y probamos el deslocking por activación, no ocurre nada; el dispositivo parece permanecer dormido, y la aplicación parece no hacer nada en absoluto (sin alarma).

He utilizado esta publicación sobre el uso de PowerManager y KeyguardManager , y esta publicación usa indicadores de ventana.

Aquí está el código utilizado actualmente para activar el dispositivo:

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

De los comentarios y publicaciones sobre algunas de las otras preguntas de SO que he visto / usado, parece que el código de PowerManager / KeyguardManager debería haber hecho el truco. De nuevo, como dije antes, funciona técnicamente mientras el dispositivo está conectado a través de USB a la máquina de desarrollo, pero no hace absolutamente nada mientras el dispositivo está separado.

También tenga en cuenta que esta es nuestra primera aplicación de Android, por lo que somos conscientes de que podríamos estar completamente equivocados en lo que estamos tratando de hacer. Cualquier sugerencia es bienvenida.

En resumen, dado el código anterior, ¿por qué el dispositivo se comporta de forma diferente en función de si está enchufado y qué deberíamos cambiar para activar y desbloquear el dispositivo como se describe? ¡Gracias de antemano por su ayuda!

Resolví el problema. La razón por la que observamos un comportamiento diferente cuando el dispositivo se enchufaba a través de USB era porque la CPU del dispositivo no se iba a dormir. Supongo que esto es el resultado de la configuración del modo de depuración, o simplemente cómo se comporta cuando está conectado a una computadora, ya que la función de ahorro de energía de la CPU para dormir sería irrelevante. Obviamente, cuando el dispositivo no está enchufado, la CPU tomaría felizmente una siesta, y si bien observamos la aplicación ejecutándose aleatoriamente (se despertaba a sí misma en momentos aleatorios), el tiempo sería inconsistente. Además, asumo que esto se debe a que los pocos ciclos de CPU que se produjeron se asignan con moderación, y nuestra aplicación recibiría muy pocos ciclos en momentos “aleatorios”.

Así que nuestra solución fue agarrar un locking parcial de activación cuando el dispositivo está en segundo plano (lo que se hace en el método onPause ) y liberar el locking en el método onResume . Esto parece evitar que la CPU duerma. Continuamos utilizando el locking completo de wake y keyguard para activar el dispositivo cuando es necesario. Usar el locking de activación parcial parece evitar que la CPU se apague y el dispositivo parece despertarse correctamente cuando se espera. Aquí está nuestro código actualizado, en caso de que alguien se encuentre con este problema:

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