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.
quelle
Antworten:
Grundsätzlich ist es ein Problem mit meinem Telefon. Andere Benutzer haben berichtet, dass dies auch bei ihren Handys von verschiedenen Marken, aber derselben Android-Version der Fall ist. Andere Personen haben überhaupt kein Problem - was stark darauf hinweist, dass dies kein Problem mit der Standardversion von Android ist, sondern mit den Implementierungen jedes Unternehmens für ihre Hardwaretreiber.
Ich benötige konstante Beschleunigungsmesserdaten und kann diese Daten nicht von einem Dongle messen lassen. Ich habe einen Arduino mit Bluetooth und Beschleunigungsmesser, daher hätte ich diese Lösung implementieren können. Also entschied ich, dass die vorübergehende Lösung für mein Handy darin bestand, den Bildschirm einzuschalten (gedimmt) und den Batterieverbrauch zu ignorieren. Später werde ich die Tests für den Akkuverbrauch mit einem anderen Android-Handy durchführen, das bei ausgeschaltetem Bildschirm funktioniert.
Weitere Informationen zum Fehler
Ich habe noch mehr recherchiert und Berichte von anderen Android-Nutzern gefunden, und ich glaube, ich verstehe, was passiert. Die Bibliothek libsensors.so mit den Treibern für die Telefonsensoren wurde nicht von Google entwickelt, sondern von jedem Mobiltelefonhersteller - natürlich, da jedes Mobiltelefon über eine eigene Hardware verfügt. Google stellt nur eine C-Header-Datei zur Verfügung, damit die Entwickler wissen, was sie implementieren müssen. Bei einigen Implementierungen für diese Treiber schalten die Entwickler den Beschleunigungsmesser einfach aus, wenn der Bildschirm ausgeht, wodurch verhindert wird, dass der Sensorereignis-Listener neue Ereignisse empfängt.
Ich habe dies auch mit CyanogenMod RC7.2 getestet, aber es hat auch nicht funktioniert, da die Beschleunigungsmesser-Treiber original von LG sind.
E-Mails mit der Personalabteilung von LG ausgetauscht
Ich habe eine E-Mail an die Entwickler des LG P990 gesendet und endlich konkrete Antworten bekommen! Dies kann für einige Leute wie mich, die diese Probleme mit Android haben, eine große Hilfe sein. Ich habe die folgende Frage geschrieben
Für das, was ich diese Antwort erhalten habe:
Ich schickte dann eine E-Mail zurück und sagte unter anderem, dass ich dies als Fehler betrachte, da man beim Erwerb einer Wecksperre Zugriff auf die gesamte Hardware haben sollte:
Und dann erhielt ich diese Antwort:
Sie wissen anscheinend davon, versuchen aber nicht, dies zu korrigieren, weil sie entweder nicht glauben, dass es sich um einen Fehler handelt - was ich immer noch für einen logischen Fehler halte - oder sie haben nicht die Zeit / Ressourcen, um ihn zu korrigieren.
Fazit Wenn Sie ein Mobiltelefon haben, das bei ausgeschaltetem Bildschirm keine Beschleunigungsmesserereignisse sendet, aktualisieren Sie Ihre Firmware. Wenn sich dies nicht lösen lässt und Sie wirklich ernsthaft hacken möchten, implementieren Sie Ihre Hardwareschicht erneut - Hinweis: Dies hat wahrscheinlich etwas mit libsensors.so zu tun.
quelle
Ich bin nicht sicher, ob dies Ihnen tatsächlich helfen wird, aber ich habe eine Lösung gefunden (Ich bin mir nicht sicher, wie gut es helfen wird, die Batterie zu schonen).
Mit bash habe ich eine while-Schleife
/sys/devices/virtual/accelerometer/accelerometer/acc_file
, und wenn ich den Bildschirm über den Netzschalter ausschalte, wird die Ausgabe fortgesetzt, aber eingefroren. (Ich hatte sshd in einer Chroot laufen lassen, daher die Fähigkeit, es zu sehen.)Allerdings im Echo
0 > /sys/devices/platform/msm_fb.196609/leds/lcd-backlight/brightness
. Der Bildschirm wird ausgeschaltet und die Ausgabe erfolgt kontinuierlich.Dies ist auf einem SGH-T589W, auf dem Android Version 2.3.6 ausgeführt wird.
quelle
Ich habe das PARTIAL_WAKE_LOCK angewendet und es hat mir sehr gut gefallen. Getestet unter OS 5.0, 6.0 und 7.0. Hier ist mein Code zum Erfassen und Freigeben der Wecksperre. Achten Sie darauf, dass der Akku entladen wird. Erfassen und lösen Sie ihn daher auf intelligente Weise.
public void acquireWakeLock() { final PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); releaseWakeLock(); //Acquire new wake lock mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PARTIAL_WAKE_LOCK"); mWakeLock.acquire(); } public void releaseWakeLock() { if (mWakeLock != null && mWakeLock.isHeld()) { mWakeLock.release(); mWakeLock = null; } }
Ref: https://developer.android.com/training/scheduling/wakelock.html#cpu
Ich arbeite an einem Vorhersage-SDK, der Gerätesensordaten (Beschleunigungsmesser / Gyroskop) verwendet und die Benutzerereignisse vorhersagt. Ich habe das gleiche Problem erlebt.
quelle
Ich bin auf ähnliche Probleme mit dem Samsung Nexus gestoßen , auf dem Android 4.0.2 mit anderen Systemdiensten ausgeführt wird, die anhalten / pausieren, während der Bildschirm ausgeschaltet ist, obwohl a
PARTIAL_WAKE_LOCK
erworben wurde. Meine Lösung bestand darin, aSCREEN_DIM_WAKE_LOCK
wie in zu verwenden:lockStatic = mgr.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,NAME);
Es wäre weitaus besser, den Bildschirm vollständig auszuschalten, aber zumindest funktioniert diese Lösung, obwohl es noch besser wäre, wenn ich die Verwendung von a
SCREEN_DIM_WAKE_LOCK
nur auf die Geräte / Betriebssysteme beschränken könnte, die dies erfordern.quelle
Ich hasse es, Sie zu enttäuschen, aber einige Geräte lassen Acceleromet einfach nicht eingeschaltet, während sie sich im Ruhemodus befinden. Einige tun es, andere nicht. Sie können jede Schrittzähler-App zur Gewichtsreduktion im Geschäft überprüfen. Die meisten von ihnen geben ausdrücklich an, dass dies auf einigen Geräten nicht funktioniert.
quelle
Wenn die Option für die teilweise Nachlaufsperre für Ihr Telefon nicht verfügbar ist, bedeutet dies, dass der Treiber für den Sensor
early_suspend
aktiviert wurde.Es gibt zwei Möglichkeiten.
1:
EARLY_SUSPEND
Im Treiber deaktivieren2: Fügen Sie einen Laufzeit - Flag , das kann
enable
/disable early_suspend
Funktionalität auf Treiberebene.Ex. Katze / System / Modul / Frühsuspend / Sensor 1/0
IMO sollte die zweite Option von Anfang an da gewesen sein.
quelle