Sto sviluppando un'applicazione per la mia tesi finale sull'informatica e ho bisogno di raccogliere e registrare i dati dell'accelerometro. Ho bisogno di acquisirlo per un giorno intero, quindi ci sono limiti di batteria (per esempio, non posso lasciare lo schermo acceso). Inoltre, questa non è un'applicazione mirata al mercato, quindi è abbastanza accettabile fare un serio hacking, anche la codifica C/C++ di basso livello, se necessario.L'accelerometro Android non funziona quando lo schermo è spento
È risaputo che su molti dispositivi gli ascoltatori di eventi accelerometrici interrompono la generazione di eventi quando lo schermo si spegne (alcuni collegamenti relativi a questo problema: http://code.google.com/p/android/issues/detail?id=3708, Accelerometer stops delivering samples when the screen is off on Droid/Nexus One even with a WakeLock). Ho cercato accuratamente alcune alternative, alcune includono soluzioni alternative che non funzionano per il mio dispositivo (LG P990, stock ROM).
Quindi, ciò che accade è questo: Quando si registra un listener di eventi per sensore accelerometro Android in un servizio, funziona fino allo spegnimento dello schermo. Ho già provato a registrare eventListener su un servizio, su un IntentService, provato ad acquisire WakeLock. Per quanto riguarda i wakelock, posso verificare che il servizio sia ancora in esecuzione guardando l'output di LOGcat, ma sembra che l'accelerometro sia messo in modalità di sospensione. Una delle soluzioni presentate in alcuni dei collegamenti è quello di annullare la registrazione e ri-registrare il listener di eventi periodicamente utilizzando il filo di un IntentService come in questo frammento di codice muggito
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
protected void onHandleIntent(Intent intent) {
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
synchronized (this) {
boolean run = true;
while (run){
try {
wait(1000);
getLock(AccelerometerService.this).acquire();
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
Log.d("Accelerometer service", "tick!");
} catch (Exception e) {
run = false;
Log.d("Accelerometer service", "interrupted; cause: " + e.getMessage());
}
}
}
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," + event.values[2]);
}
che rende davvero l'onSensorChange essere chiamato ogni volta che ci annullare la registrazione/registrare l'ascoltatore. Il problema è che l'evento ricevuto contiene sempre gli stessi valori, indipendentemente dal fatto che io scuoti il dispositivo.
Quindi, in pratica le mie domande sono: (porto con me, ho quasi terminato: P)
è possibile avere accesso a basso livello (C/C++ approccio) per l'hardware accelerometro SENZA registrarsi ad un ascoltatore di eventi?
c'è qualche altra soluzione o hack?
qualcuno con un telefono più aggiornato potrebbe verificare se il problema persiste nel firmware 3.0 e versioni successive?
[UPDATE]
Purtroppo, sembra essere un bug con alcuni cellulari. Maggiori dettagli nella mia risposta.
Ciao. Ho appena testato il problema con il mio HTC Sensation (ICS). Sia l'accelerometro che il sensore del campo magnetico continuavano a riportare i valori con lo schermo spento. Inoltre, hai controllato la soluzione alternativa descritta nel commento [46] (http://code.google.com/p/android/issues/detail?id=3708)? – Renard
Grazie per il feedback Renard. Riguardo al commento 46, ho anche provato che, è quasi lo stesso approccio come eseguire un thread che annulla la registrazione/registrazione di un listener di eventi .. Ma con il mio dispositivo ottengo solo valori fissi per l'accelerometro ogni volta che spengo il mio display .. Grazie anche per averlo testato su ICS ... è bello sapere che funziona come dovrebbe, purtroppo non c'è ancora ICS per LG P990 =/ – martin
Potrebbe essere utile provare a risolvere il problema da altro lato: acquisire il blocco dello schermo, ma allo stesso tempo ridurre la luminosità dello schermo a zero per risparmiare la batteria? Certo, non funziona quando si spegne lo schermo con il pulsante di accensione, ma in questo caso si può provare a riattivare il dispositivo per impedire il blocco dello schermo. –