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

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.

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(); }}); } } }; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.