Ich entwickle eine Anwendung für meine Abschlussarbeit über Informatik und muss Beschleunigungsmesserdaten sammeln und protokollieren. Ich muss es einen ganzen Tag lang erwerben, daher gibt es ernsthafte Batteriebeschränkungen (zum Beispiel kann ich den Bildschirm nicht eingeschaltet lassen). Dies ist auch keine marktgerechte Anwendung, daher ist es ziemlich akzeptabel, ernsthafte Hacking-Aktionen durchzuführen, bei Bedarf sogar C / C ++ - Codierungen auf niedriger Ebene.
Es ist bekannt, dass auf vielen Geräten die Listener für Beschleunigungsmesserereignisse keine Ereignisse mehr generieren, wenn der Bildschirm ausgeht (einige Links zu diesem Problem: http://code.google.com/p/android/issues/detail?id=3708 , Beschleunigungsmesser liefert keine Proben mehr, wenn der Bildschirm auf Droid / Nexus One auch mit einem WakeLock ausgeschaltet ist . Ich habe gründlich nach Alternativen gesucht. Einige davon enthalten Problemumgehungen, die für mein Gerät nicht funktionieren (LG P990, Standard-ROM).
Was also passiert, ist Folgendes: Wenn Sie einen Ereignis-Listener für einen Android-Beschleunigungssensor in einem Dienst registrieren, funktioniert dies einwandfrei, bis der Bildschirm ausgeschaltet wird. Ich habe bereits versucht, den eventListener in einem Dienst zu registrieren, in einem IntentService, und versucht, WakeLocks zu erwerben. In Bezug auf Wakelocks kann ich überprüfen, ob der Dienst noch läuft und die LOGcat-Ausgabe überwacht, aber es scheint, dass der Beschleunigungsmesser in den Ruhemodus versetzt wurde. Eine der Problemumgehungen, die in einigen Links vorgestellt wird, besteht darin, die Registrierung des Ereignis-Listeners regelmäßig mithilfe des Threads eines IntentService wie in diesem Code-Snippet unten aufzuheben und erneut zu registrieren
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]);
}
Dadurch wird der onSensorChange jedes Mal aufgerufen, wenn wir den Listener abmelden / registrieren. Das Problem ist, dass das empfangene Ereignis immer dieselben Werte enthält, unabhängig davon, ob ich das Gerät geschüttelt habe.
Also, im Grunde sind meine Fragen: (ertrage es mit mir, ich bin fast fertig: P)
Ist es möglich, auf niedriger Ebene (C / C ++ - Ansatz) auf die Beschleunigungsmesser-Hardware zuzugreifen, ohne sich bei einem Ereignis-Listener zu registrieren?
Gibt es eine andere Problemumgehung oder einen anderen Hack?
Könnte jemand mit einem aktuelleren Telefon freundlich testen, ob das Problem in Firmware 3.0 und höher weiterhin besteht?
[AKTUALISIEREN]
Leider scheint es bei einigen Handys ein Fehler zu sein. Weitere Details in meiner Antwort.