SensorEventListener не становится незарегистрированным с помощью метода unregisterListener () - PullRequest
28 голосов
/ 03 августа 2011

У меня очень простое приложение для Android: в действии у меня есть кнопка, и я запускаю / останавливаю OrientationListener.Однако после отмены регистрации в ddms я все еще вижу поток android.hardware.SensorManager $ SensorThread] (Running) .

Регистрационный код:

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

и отмена регистрации:

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

Метод unregisterListener() выполняется, однако он не очень сильно прерывает поток датчиковчасто, который продолжает работать и разряжать батарею.Через несколько часов мое приложение отображается с 20-30% разряда батареи.Как это возможно?Как я могу убедиться, что датчик становится незарегистрированным?Я не получаю никаких исключений или ошибок в logcat.Я попытался запустить слушатель в Сервисе - тоже самое.

Ответы [ 7 ]

3 голосов
/ 20 апреля 2016

В моем случае, чтобы решить эту проблему, мне нужно было исправить контекст, который я использовал для получения SensorManager. Я был внутри Службы, и мне нужно было получить SensorManager следующим образом:

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

Итак, просто подтвердите, правильно ли вы получаете SensorManager.

3 голосов
/ 14 октября 2012

Вы не показываете достаточно кода, чтобы сказать наверняка, но, возможно, ваш тест

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

просто не точен.То есть sensorManager или sensorEventListener может быть null, если вы все еще зарегистрированы как слушатели.

2 голосов
/ 19 октября 2015

Я столкнулся с подобной проблемой.

Обходной путь для остановки датчика.

Я использовал статическое логическое значение mIsSensorUpdateEnabled.Установите значение «false», если вы хотите прекратить получать значения от датчиков.А в методе onSensorChanged () проверьте значение логической переменной и снова вызовите, чтобы отменить регистрацию датчиков.И на этот раз это работает.Датчики будут незарегистрированными, и вы больше не получите обратный вызов SensorChanged.

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
    }
}
2 голосов
/ 08 февраля 2012

У меня такая же проблема. Я проверил код Android. Соответствующий код находится в 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;
            }
        }
    }
}

и

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

Похоже, что поток должен быть прерван, когда слушателей больше нет

2 голосов
/ 28 октября 2011

Попробуйте установить менеджер на ноль

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

и затем снова получите менеджера, когда вам это нужно. Это должно привести к завершению потока последовательно (в моем случае). Я не нашел никаких документов, объясняющих это поведение, но мне было бы интересно узнать об этом.

1 голос
/ 03 августа 2011

Может быть проблема с областью действия.Попробуйте записать значения sensorEventListener и sensor при регистрации и отмене их регистрации.(.toString ()), чтобы убедиться, что они совпадают.

0 голосов
/ 28 декабря 2016
//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();
    }

Пожалуйста, позвоните на Destroy

if (sensorManager != null && mAccelerometer != null) 
{ 
    sensorManager.unregisterListener(sensorEventListener, mAccelerometer); sensorManager = null; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...