Der Android-Beschleunigungsmesser funktioniert nicht, wenn der Bildschirm ausgeschaltet ist

70

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)

  1. Ist es möglich, auf niedriger Ebene (C / C ++ - Ansatz) auf die Beschleunigungsmesser-Hardware zuzugreifen, ohne sich bei einem Ereignis-Listener zu registrieren?

  2. Gibt es eine andere Problemumgehung oder einen anderen Hack?

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

Martin
quelle
1
Hallo. Ich habe das Problem gerade mit meinem HTC Sensation (ICS) getestet. Sowohl der Beschleunigungsmesser als auch der Magnetfeldsensor meldeten Werte bei ausgeschaltetem Bildschirm. Haben Sie auch die in Kommentar 46 beschriebene Problemumgehung überprüft ?
Renard
1
Könnte es nützlich sein, das Problem von der anderen Seite zu lösen - Bildschirmsperre zu erlangen, aber gleichzeitig die Bildschirmhelligkeit auf Null zu reduzieren, um den Akku zu schonen? Sicher, es funktioniert nicht, wenn Sie den Bildschirm mit dem Netzschalter ausschalten, aber in diesem Fall können Sie versuchen, das Gerät zu aktivieren, um zu verhindern, dass der Bildschirm blockiert.
Andrey Starodubtsev
1
Ich habe kürzlich Beschleunigungsmesser und Magnetometer an mehreren Androiden verschiedener Modelle protokolliert und bin nie auf dieses Problem gestoßen. Meine Modelle enthielten ein paar HTCs und ein Samsung Captivate, also war es wohl keine so große Auswahl. Aber vielleicht, wenn dies Ihre These ist, lohnt es sich, zumindest vorübergehend mit Ihrem Kumpel zu telefonieren, um Ihre Protokolle zu erhalten. Sie können auch in Betracht ziehen, mit einem DIM-Bildschirm-Wakelock zu arbeiten und weniger häufig zu protokollieren, das Telefon jeweils 5 Minuten lang in den Ruhezustand zu versetzen und regelmäßig aufzuwachen, um einige Proben zu entnehmen. Dazu verwenden Sie AlarmManager und BroadcastReciever.
Mwengler
3
Martin, ich denke, Sie haben die Frage selbst beantwortet, also sollten Sie eine Antwort auf Ihre Frage erstellen und akzeptieren und alle Ergebnisse darin einfügen.
Renard
1
Ist es eine Option, dafür einen eigenständigen Beschleunigungsmesser zu verwenden, wie den von Shimmer Research, der die Daten über Bluetooth sendet? Sie können sogar ganz einfach Ihre eigene Firmware auf diese schreiben und flashen : shimmer-research.com Ich habe selbst mit ihnen gearbeitet und sie funktionieren (und arbeiten mit Android) - obwohl Sie ihre Akkulaufzeit untersuchen müssen.
Thomas Dignan

Antworten:

71

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

Hallo! Ich entwickle meine Diplomarbeit in Informatik und rufe derzeit Daten von der Beschleunigungsmesser-Hardware ab. Ab sofort habe ich festgestellt, dass die Beschleunigungsmesser keine Ereignisse senden, wenn der Bildschirm ausgeschaltet ist. Selbst wenn ich ein Wakelock aus einem meiner Programme heraus greife, kann ich überprüfen, ob mein Programm noch ausgeführt wird (über die LOGcat-Ausgabe), aber nein Beschleunigungsmesser Ereignis kommt heraus. Ich muss meinen Bildschirm einschalten (was ich mir nicht leisten kann, der Akku wird zu schnell entladen), um wieder Beschleunigungsmesser-Ereignisse zu empfangen. Ich habe auch versucht, über nativen C-Code darauf zuzugreifen und mich bei den Beschleunigungsmesserereignissen zu registrieren, aber das Ergebnis war das gleiche. Der Beschleunigungsmesser hat keine Werte ausgegeben, obwohl ich mein Gerät gedreht habe. Ich fragte mich also, ob ich mit nativem Code direkten Zugriff auf die Hardware haben könnte, ohne mich bei einem Listener registrieren zu müssen. Ist das möglich? Wenn ja, können Sie uns bitte weitere Ratschläge geben? Ich würde mich über jede Hilfe sehr freuen! Martin

Für das, was ich diese Antwort erhalten habe:

Lieber Martin, wir haben die Antwort von Dev erhalten. Mannschaft. Sie sagten, dass Sie kein Beschleunigungsmesser-Ereignis erhalten können, während Ihr Telefonbildschirm ausgeschaltet ist. Da die HAL-Schicht keinen sysFS-Pfad implementiert hat, um ein H / W-Ereignis wie einen Beschleunigungsmesser abzurufen, und es keine öffentliche API gibt, um ein Ereignis abzurufen. Vielen Dank. Freundliche Grüße. (Sean Kim)

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:

[...] Ich habe diese Frage gestellt, weil ich einige Freunde habe, die auch Android-Telefone mit derselben Lebkuchenversion, aber von anderen Mobiltelefonmarken haben, und einige von ihnen berichteten, dass sie Ereignisse von den Beschleunigungsmessern erhalten, wenn der Bildschirm ausgeschaltet wird. Ich habe in einigen Foren gelesen, dass dieser Fehler - ich halte ihn für einen Fehler, da ich beim Erwerb eines Wakelock eine gewisse Verarbeitung erwarten würde - von den Sensortreibern abhängt, die die Anbieter für ihre Handys implementieren. Gibt es eine Möglichkeit, dass diese Treiber aktualisiert werden können, oder wird dieser Fehler irgendwann behoben? Dies würde mir bei meiner laufenden Arbeit enorm helfen [...]

Und dann erhielt ich diese Antwort:

Nach meinem Wissen von Dev. Team, das ist kein Fehler. Aufgrund der H / W-Architektur ist dieses Telefon unbegrenzt. Wir müssen die HAL-Architektur und den Gerätetreiber neu gestalten, um Ihre Anfrage zu unterstützen. Aber wie Sie wissen, ist das aufgrund mangelnder Ressourcen zu schwierig. Wir versuchen, Ihnen bei allen Bemühungen zu helfen, können Ihre Anfrage jedoch nicht unterstützen, wie ich bereits erwähnt habe. (Sean Kim)

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.

Martin
quelle
2
Danke Martin für diese sehr vollständige Information. Was wir wirklich brauchen, ist eine Liste, in der angegeben ist, welche Telefone Beschleunigungsmesserereignisse auf dem Bildschirm unterstützen, da die Leute diese Informationen möglicherweise vor dem Kauf wünschen (wie ich - ich brauche diese). Vielleicht ein Wiki, Leute könnten ihre Telefone testen und die Liste aktualisieren. Gibt es irgendwo eine solche Liste?
Fletch
8
OK, ich habe eine Liste erstellt: saltwebsites.com/2012/android-accelerometers-screen-off
Fletch
2
Erstaunliche und wirklich umfassende Antwort. Würde mehr als einen Daumen hoch geben :) Bis zu einem gewissen Grad können Sie das Problem lösen, indem Sie SCREEN_OFF- und SCREEN_ON-Ereignisse abhören, eine neue Wecksperre erwerben und den Beschleunigungsmesserdienst neu starten. Aber auch hier funktioniert es nur auf einigen Handys.
LambergaR
subperb Weg zu Fragen und Ans
Shakeeb Ayaz
Kann Jailbreaking diesen Fehler beseitigen?
Amir
6

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.

fu-fu
quelle
Huh! Gut gespielt, denke nicht an Bash-Scripting. Ich denke, ich werde es später versuchen, obwohl ich diese Arbeit schon vor langer Zeit beendet habe. Danke für die Eingabe!
Martin
2

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.

Farhan
quelle
2

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_LOCKerworben wurde. Meine Lösung bestand darin, a SCREEN_DIM_WAKE_LOCKwie 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_LOCKnur auf die Geräte / Betriebssysteme beschränken könnte, die dies erfordern.

Greg Martin
quelle
0

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.

EvilDuck
quelle
0

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_suspendaktiviert wurde.

Es gibt zwei Möglichkeiten.

1: EARLY_SUSPENDIm Treiber deaktivieren

2: Fügen Sie einen Laufzeit - Flag , das kann enable/ disable early_suspendFunktionalität auf Treiberebene.

Ex. Katze / System / Modul / Frühsuspend / Sensor 1/0

IMO sollte die zweite Option von Anfang an da gewesen sein.

Boosth
quelle