23

Ich habe einige Code, der einen Service erweitert und erfasst OnSensorChanged (SensorEvent Ereignis) Beschleunigungssensor-Messwerte auf Android. Ich würde gerne in der Lage sein, diese Sensorwerte auch dann aufzuzeichnen, wenn das Gerät ausgeschaltet ist (ich bin vorsichtig mit der Batterielebensdauer und es wird offensichtlich, wenn es läuft). Während der Bildschirm läuft, funktioniert das Logging auf einem Motorola Droid 2.0.1 und einem 2.1 Nexus One.Accelerometer stoppt die Lieferung von Proben, wenn der Bildschirm ausgeschaltet ist Droid/Nexus One sogar mit einem WakeLock

Wenn das Telefon jedoch in den Ruhezustand wechselt (durch Drücken des Netzschalters), wird der Bildschirm ausgeschaltet und die onSensorChanged Ereignisse werden nicht mehr gesendet (verifiziert durch Verwendung einer Log.e-Nachricht alle N Male wird aufgerufen).

Der Dienst erwirbt einen wakeLock, um sicherzustellen, dass er im Hintergrund läuft. aber es scheint keine Wirkung zu haben. Ich habe alle verschiedenen PowerManager ausprobiert. Wake Locks, aber keiner von ihnen scheint eine Rolle zu spielen.

_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); 
_WakeLock.acquire(); 

Es gibt widersprüchliche Berichte gewesen darüber, ob oder nicht, können Sie tatsächlich Daten von den Sensoren erhalten, während der Bildschirm ausgeschaltet ist ... jemand mit dieser keine Erfahrung auf eine modernere Version von Android (Eclair) und Hardware ?

Dies scheint darauf hinzudeuten, dass es in Cupcake arbeitet: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5

PS: Der exakt gleiche Code in 1.5 auf einem G1 wie vorgesehen funktioniert. Die Protokollierung wird fortgesetzt, wenn sich der Bildschirm ausschaltet, wenn sich die Anwendung im Hintergrund befindet usw.

+0

Spur dieses Problem hier: http://code.google.com/p/android/issues/detail?id= 3708 –

+0

Ich habe die Antwort unten mit einer Problemumgehung, die wir gefunden haben, scheint auf den Motorola 2.0.1 Geräten wirksam. Ich werde auch melden, sobald 2.1 zur Verfügung steht, was sich auf das Problem auswirkt. – mylock

+0

Neuer Tracker für dieses Problem - immer noch in 2.2 integriert - http://code.google.com/p/android/issues/detail?id = 11028 – Artem

Antwort

8

Wir haben dies ab 2.0.1 abgeleitet. Es scheint beabsichtigt zu sein, vielleicht Teil der Akkulaufzeit, die als Feature angepriesen wurde. Wir hatten ein funktionierendes Shake, um auf 2.0 zu wecken oder zu entsperren, dann brach es das Update und wir konnten keine Art von Workaround bekommen. ; (Es spielt keine Rolle, ob die CPU-Partialsperre gehalten wird, die immer verhindern soll, dass die CPU schläft). Von dem, was ich beim Logging-Debugging über USB gesehen habe, scheint es gelegentlich Sensoränderungen zu geben, wenn der Schlaf eintritt.

ein Benutzer hat eine Problemumgehung, die er Arbeiten an den motorola Geräte beansprucht - https://sites.google.com/a/bug-br.org.br/android/technical-documents

ich die Problemumgehung getestet, mit dem folgenden Code aus dem Tutorial und einige manuellen Überarbeitung (es gibt in seinem Tutorial ein paar „Bugs“ kommen vorgestellten Code):

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"); 
      } 
     } 

Die Umgehungslösung funktioniert für mich, wird aber nicht funktionieren k, während ich screebl laufen lasse, was ein Feature ist, dass viele meiner Benutzer wirklich in Verbindung mit dem, was ich gerade entwickle, arbeiten wollen.

+1

Danke dafür; Kombiniert mit einem PARTIAL_WAKE_LOCK funktionierte die Re-Registrierungstechnik hauptsächlich für mich. Aber ich musste die Neuregistrierungsbits in einen zeitgesteuerten Ausführungsthread setzen, z. Es passiert, nachdem alle SCREEN_OFF-Aktivitäten abgeschlossen sind. Details hier: http://nosemaj.org/android-persistent-sensors – Jameson

+0

Danke für die Antwort @mylock –

1

Ich habe gerade mein Nexus One mit dem FROYO FRF50 ROM aktualisiert, das in den letzten Tagen um das Internet gekickt hat, und es scheint, dass Sensoren jetzt wieder funktionieren, wenn der Bildschirm ausgeschaltet ist, wenn Sie einen PARTIAL_WAKELOCK haben. Ich weiß nicht, ob dies zum offiziellen Build führen wird, obwohl mein Verständnis ist, dass dies auf einem offiziellen Build basiert, den einige N1 Benutzer erhalten haben. Vielleicht haben sie (noch einmal) ihre Meinung geändert und die Sensoren wieder aktiviert, wenn das Telefon gesperrt ist. Daumen drücken.

Natürlich könnten sie nur sie gehen, und deaktivieren Sie wieder in 2.2-r1, wer weiß ...

+0

Kleines Update dazu: Sie haben es nicht in 2.2 endgültig deaktiviert. Die Sensoren funktionieren, während der Bildschirm von der endgültigen Version 2.2 (FRF91) auf meinem Nexus One entfernt ist. – pableu

0

Es scheint, dass es sich um ein 2.1 Firmware-Problem ist, ist es nötig, dass ich diese reparieren zu lassen, aber ich Ich muss in allen möglichen Problemumgehungen arbeiten, um alle Versionen abzudecken.

Ich habe eine Liste von Telefonen und Firmwares zusammengestellt, die funktionieren/nicht funktionieren/zeitweise funktionieren, so dass wir entweder das Telefon oder die Firmware testen können.

http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/

Wenn Sie ein neues Handy haben Sie die Liste mit aktualisieren können, lassen Sie es mich wissen.

0

Es gibt eine alternative Lösung (Art), wo Sie den Bildschirm halten immer eingeschaltet mit:

Settings.System.putInt (getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, -1);

Das hindert den Benutzer jedoch nicht daran, den Bildschirm durch Drücken des Ein-/Ausschalters auszuschalten, und der Sensorereignisstrom stoppt. Sie benötigen auch die WRITE_SETTINGS-Berechtigung, damit dies funktioniert.

Die obige Problemumgehung der erneuten Registrierung für Sensorereignisse funktioniert nicht auf dem Droid Eris, der Android 2.1 ausführt und von dem nicht erwartet wird, dass er jemals ein Upgrade erhält. Ich habe das folgende verwendet, das scheint zu funktionieren. Anstatt sich zu registrieren und erneut zu registrieren, schaltet diese Methode den Bildschirm wieder ein, wenn der Benutzer ihn ausschaltet, obwohl er wieder abgeblendet wird. Im folgenden Code ist der Handler nur ein einfacher Handler, der in der Aktivität erstellt wurde (d. H. Handler-Handler = new Handler();) und mTurnBackOn ist ein WakeLock, der auf null initialisiert wird.

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(); 
      }}); 
     } 
    } 
}; 
1

Mit einem SCREEN_DIM_WAKE_LOCK für mich auf dem HTC EVO gearbeitet ..

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG"); 
_WakeLock.acquire(); 
+1

Einfach auch hinzufügen ... Diese Problemumgehung wird ressourcenintensiver sein, da der Bildschirm im abgeblendeten Zustand bleibt. Nach langem Suchen scheint dieses Problem bei späteren Android OS-Versionen noch nicht gelöst zu sein ... – Ashish

Verwandte Themen