unregisterlistener studio getinclination java android listener sensor

java - studio - SensorEventListener no se anula el registro con el método unregisterListener()



sensormanager getinclination (7)

Tengo una aplicación para Android muy simple: en la actividad tengo un botón y comienzo / detengo el Detector de Orientación. Sin embargo, después de anular el registro, en ddms todavía puedo ver el hilo android.hardware.SensorManager $ SensorThread] (En ejecución) .

El código de registro:

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION); if (sensors.size() > 0) { sensor = sensors.get(0); running = sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_FASTEST); }

y anulación del registro:

try { if (sensorManager != null && sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener,sensor); running = false; } } catch (Exception e) { Log.w(TAG, e.getMessage()); }

El método unregisterListener() se ejecuta, sin embargo, no mata el hilo de los sensores muy a menudo, lo que sigue funcionando y agotando la batería. Después de unas horas, mi aplicación aparece con un 20-30% de descarga de la batería. ¿Cómo es eso posible? ¿Cómo puedo asegurarme de que el sensor quede sin registrar? No obtengo ninguna excepción ni error en el logcat. Intenté ejecutar el oyente en el Servicio - lo mismo.


En mi caso, para resolver este problema necesitaba corregir el contexto que estaba usando para obtener SensorManager. Estaba dentro de un Servicio, y necesitaba obtener el SensorManager de esta manera:

SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(SENSOR_SERVICE);

Entonces, solo certifique si está obteniendo el SensorManager de la manera correcta.


Estoy teniendo el mismo problema. Revisé el código de Android. El código relevante está en SensorManager.java

private void unregisterListener(Object listener) { if (listener == null) { return; } synchronized (sListeners) { final int size = sListeners.size(); for (int i=0 ; i<size ; i++) { ListenerDelegate l = sListeners.get(i); if (l.getListener() == listener) { sListeners.remove(i); // disable all sensors for this listener for (Sensor sensor : l.getSensors()) { disableSensorLocked(sensor); } break; } } } }

y

public void run() { //Log.d(TAG, "entering main sensor thread"); final float[] values = new float[3]; final int[] status = new int[1]; final long timestamp[] = new long[1]; Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); if (!open()) { return; } synchronized (this) { // we''ve open the driver, we''re ready to open the sensors mSensorsReady = true; this.notify(); } while (true) { // wait for an event final int sensor = sensors_data_poll(sQueue, values, status, timestamp); int accuracy = status[0]; synchronized (sListeners) { if (sensor == -1 || sListeners.isEmpty()) { // we lost the connection to the event stream. this happens // when the last listener is removed or if there is an error if (sensor == -1 && !sListeners.isEmpty()) { // log a warning in case of abnormal termination Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor); } // we have no more listeners or polling failed, terminate the thread sensors_destroy_queue(sQueue); sQueue = 0; mThread = null; break; } final Sensor sensorObject = sHandleToSensor.get(sensor); if (sensorObject != null) { // report the sensor event to all listeners that // care about it. final int size = sListeners.size(); for (int i=0 ; i<size ; i++) { ListenerDelegate listener = sListeners.get(i); if (listener.hasSensor(sensorObject)) { // this is asynchronous (okay to call // with sListeners lock held). listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy); } } } } } //Log.d(TAG, "exiting main sensor thread"); } } }

Así que parece que el hilo debe terminar cuando ya no hay oyentes


Intenta establecer el administrador en nulo

sensorManager.unregisterListener(sensorEventListener,sensor); sensorManager = null;

y luego volver a obtener el administrador cuando lo necesite. Esto debería hacer que el hilo termine consistentemente (lo hizo en mi caso). No he encontrado ninguna documentación que explique este comportamiento, pero me interesaría saberlo.


Me enfrenté a un problema similar.

Solución para detener el sensor.

Utilicé un mIsSensorUpdateEnabled booleano mIsSensorUpdateEnabled . Establézcalo en ''falso'' cuando desee dejar de obtener valores de los sensores. Y en el método onSensorChanged (), verifique el valor de la variable booleana y nuevamente haga una llamada para cancelar el registro de los sensores. Y esta vez, funciona. Los sensores no se registrarán y ya no obtendrá la devolución de llamada en SensChanged.

public class MainActivity extends Activity implements SensorEventListener { private static boolean mIsSensorUpdateEnabled = false; private SensorManager mSensorManager; private Sensor mAccelerometer; @override protected void onCreate(){ mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); } private startSensors(){ mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); int delay = 100000; //in microseconds equivalent to 0.1 sec mSensorManager.registerListener(this, mAccelerometer, delay ); mIsSensorUpdateEnabled =true; } private stopSensors(){ mSensorManager.unregisterListener(this, mAccelerometer); mIsSensorUpdateEnabled =false; } @Override public void onSensorChanged(SensorEvent event) { if (!mIsSensorUpdateEnabled) { stopSensors(); Log.e("SensorMM", "SensorUpdate disabled. returning"); return; } //Do other work with sensor data } }


No muestra el código suficiente para decirlo con seguridad, pero tal vez su prueba

if (sensorManager != null && sensorEventListener != null)

simplemente no es exacto. Es decir, sensorManager o sensorEventListener puede ser null cuando aún está registrado como escucha.


Podría ser un problema con el alcance. Intente registrar los valores de sensorEventListener y sensor cuando se registre y anule el registro. (.toString ()) para asegurarse de que sean iguales.


//Declaration of SensorManager private SensorManager sensorManager; private Sensor mAccelerometer; private SensorEventListener sensorEventListener;

onCreate call To

try { sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); sensorManager.registerListener(sensorEventListener=new SensorEventListener() { int orientation = -1; @Override public void onSensorChanged(SensorEvent event) { if (event.values[1] < 6.5 && event.values[1] > -6.5) { if (orientation != 1) { Log.d("Sensor", "Landscape"); } orientation = 1; } else { if (orientation != 0) { Log.d("Sensor", "Portrait"); } orientation = 0; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }, mAccelerometer=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); } catch (Exception e) { e.printStackTrace(); }

Por favor llame al para destruir

if (sensorManager != null && mAccelerometer != null) { sensorManager.unregisterListener(sensorEventListener, mAccelerometer); sensorManager = null; }