El acelerómetro detiene la entrega de muestras cuando la pantalla está apagada en Droid / Nexus One incluso con un WakeLock
Tengo un código que extiende un servicio y registra las lecturas del sensor del acelerómetro onSensorChanged (SensorEvent event) en Android. Quisiera poder registrar estas lecturas del sensor incluso cuando el dispositivo está apagado (soy cuidadoso con la vida de la batería y se hace obvio cuando está funcionando). Mientras que la pantalla está en el registro funciona bien en un 2.0.1 Motorola Droid y un 2.1 Nexus One.
Sin embargo, cuando el teléfono se detiene (pulsando el botón de encendido), la pantalla se apaga y los eventos onSensorChanged
dejan de ser entregados (verificados mediante un mensaje Log.e cada N veces que onSensorChanged
se llama).
- Leer la entrada de energía de usb
- ¿Los receptores de radiodifusión para Android consumen la vida de la batería?
- Android: la actividad se ha filtrado IntentReceiver
- El estado de la batería no se está cargando
- Reconocer las pulsaciones del botón de volumen cuando la pantalla está desactivada Android
El servicio adquiere un wakeLock para asegurarse de que sigue funcionando en segundo plano; Pero, no parece tener ningún efecto. He probado todos los PowerManager diferentes. Despertar cerraduras pero ninguno de ellos parecen importar.
_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); _WakeLock.acquire();
Ha habido informes contradictorios sobre si o no se puede obtener datos de los sensores, mientras que la pantalla está apagada … alguien tiene alguna experiencia con esto en una versión más moderna de Android (Eclair) y hardware?
Esto parece indicar que estaba funcionando en Cupcake: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5
PS: El mismo código funciona exactamente como se pretende en 1.5 en un G1. El registro continúa cuando la pantalla se apaga, cuando la aplicación está en segundo plano, etc.
- Uso de la batería, ¿qué esperar?
- ¿Cómo se interpreta WAKEUP_STAT y WAKEUP_INTx_PEND en exynos SoC kmsg?
- Android BroadcastReceiver android.intent.action.BATTERY_CHANGED
- ¿Hay alguna manera de recibir un evento de espera de la CPU en Android?
- Android Estática Variable Alcance y Vida útil
- Cómo mantener el dispositivo Android de dormir mientras está conectado
- Android: uso de la batería de cada aplicación
Hemos deducido esto empezó como de 2.0.1. Parece ser intencional, tal vez parte de la vida de la batería impulso que se promociona como una característica. Tuvimos un batido de trabajo para despertar o desbloquear en 2.0, luego se rompió en la actualización y no hemos sido capaces de obtener ningún tipo de solución. (No importa si se lleva a cabo el bloqueo parcial de la CPU, que se supone que siempre evitará que la CPU duerma.) De lo que he visto el registro de depuración a través de USB, parece que ocasionalmente se mencionan los cambios del oyente del sensor como el sueño.
Un usuario publicó una solución que afirmó que funcionaba en los dispositivos Motorola: https://sites.google.com/a/bug-br.org.br/android/technical-documents
He probado la solución, llegando con el siguiente código del tutorial y algunos manual de revisión (hay algunos "errores" en su tutorial presentado código):
public class ShakeWakeupService extends Service implements SensorEventListener{ private Context mContext; SensorManager mSensorEventManager; Sensor mSensor; // BroadcastReceiver for handling ACTION_SCREEN_OFF. public BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Check action just to be on the safe side. if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { Log.v("shake mediator screen off","trying re-registration"); // Unregisters the listener and registers it again. mSensorEventManager.unregisterListener(ShakeWakeupService.this); mSensorEventManager.registerListener(ShakeWakeupService.this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } } }; @Override public void onCreate() { super.onCreate(); Log.v("shake service startup","registering for shake"); mContext = getApplicationContext(); // Obtain a reference to system-wide sensor event manager. mSensorEventManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); // Get the default sensor for accel mSensor = mSensorEventManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // Register for events. mSensorEventManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver // code be called whenever the phone enters standby mode. IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(mReceiver, filter); } @Override public void onDestroy() { // Unregister our receiver. unregisterReceiver(mReceiver); // Unregister from SensorManager. mSensorEventManager.unregisterListener(this); } @Override public IBinder onBind(Intent intent) { // We don't need a IBinder interface. return null; } public void onShake() { //Poke a user activity to cause wake? } public void onAccuracyChanged(Sensor sensor, int accuracy) { //not used right now } //Used to decide if it is a shake public void onSensorChanged(SensorEvent event) { if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return; Log.v("sensor","sensor change is verifying"); } }
La solución funciona para mí, pero no funcionará mientras tengo screebl en ejecución, que es una característica que muchos de mis usuarios realmente quieren trabajar en conjunto con lo que estoy desarrollando.
Acabo de actualizar mi Nexus One con la FROYO FRF50 ROM que ha estado dando vueltas alrededor de los internets para los últimos días, y parece que los sensores ahora funcionan de nuevo cuando la pantalla está apagada si usted tiene un PARTIAL_WAKELOCK. No sé si esto lo hará a la compilación oficial, aunque mi comprensión es que esto se basa en una compilación oficial que algunos N1 usuarios recibieron. Así que tal vez han cambiado de opinión (una vez más), y volver a activar los sensores cuando el teléfono está bloqueado. Dedos cruzados.
Por supuesto, podrían simplemente ir y deshabilitarlos de nuevo en 2.2-r1, quien sabe …
El uso de un SCREEN_DIM_WAKE_LOCK
funcionó para mí en el HTC EVO ..
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); _WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG"); _WakeLock.acquire();
Parece que es un problema de firmware 2.1, es necesario para mí conseguir esto fijo, pero tengo que trabajar en todo tipo de soluciones para cubrir todas las versiones.
He estado elaborando una lista de teléfonos y firmwares que funcionan / no funcionan / de forma intermitente para que podamos probar el teléfono o el firmware.
http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/
Si tiene un teléfono nuevo con el que puede actualizar la lista, háganmelo saber.
Hay una solución alternativa (tipo de) donde se mantiene la pantalla siempre encendida utilizando:
Settings.System.putInt (getContentResolver (), Settings.System.SCREEN_OFF_TIMEOUT, -1);
Pero esto no impide que el usuario obligue a la pantalla a apagarse pulsando el botón de encendido y, a continuación, el flujo de eventos del sensor se detiene. También necesita el permiso WRITE_SETTINGS para que esto funcione.
La solución anterior de volver a registrar eventos de sensor no funciona en el Droid Eris, que ejecuta Android 2.1 y no se espera que alguna vez obtener una actualización. He utilizado el siguiente aunque que parece funcionar. En lugar de desconectarse y volver a registrarse, este enfoque vuelve a activar la pantalla cuando el usuario la apaga, aunque vuelve a atenuarse. En el código siguiente, el manejador es simplemente un manejador simple construido en la Actividad (es decir, Handler handler = new Handler ();) y mTurnBackOn es un WakeLock inicializado a null.
public BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { // Turn the screen back on again, from the main thread handler.post(new Runnable() { public void run() { if(mTurnBackOn != null) mTurnBackOn.release(); mTurnBackOn = mPwrMgr.newWakeLock( PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "AccelOn"); mTurnBackOn.acquire(); }}); } } };