Получить только 1 событие от датчика

Я пытаюсь получить только 1 событие от датчика ориентации.

Мой код:

@Override
public void onSensorChanged(SensorEvent event) {
Log(event);
unregisterSensor(...);
}

Затем в потоке каждые 1000 мс я делаю:

registerSensor();
Thread.sleep(2000);

Проблема в том, что если я отменю регистрацию датчика в конце метода (как я сделал), то в следующий раз (когда я перерегистрирую датчик) он будет регистрировать то же событие значения, которое было поймано ранее (при перемещении телефона) . Если я даю onSensorChanged возможность запускаться дважды (используя счетчик), то он обнаруживает правильное значение и дважды регистрирует это значение.

В чем проблема с методом, вызываемым только один раз?


person Hoconosc    schedule 12.10.2012    source источник


Ответы (2)


Согласно вашему коду, в onSensorChanged() вы регистрируете myevent, а не event, которое вы получаете в качестве аргумента.

Кроме того, почему бы вам не указать LocationManager отправлять вам новые события только каждые 1 или 2 секунды вместо всех этих хлопот с регистрацией и отменой регистрации? Вы можете сделать это, используя параметр minTime метода LocationManager#requestLocationUpdates().

person Ridcully    schedule 12.10.2012
comment
myevent — моя ошибка, код намного длиннее. Но мне не нужна ориентация, чтобы получить GPS-положение телефона. Я использую датчик ориентации только для определения наклона телефона. - person Hoconosc; 12.10.2012
comment
В API есть метод getOrientation или аналогичный, чтобы получить наклон телефона (я посмотрю его позже) и опубликовать здесь, если вы не можете его найти. - person Ridcully; 12.10.2012
comment
Я использую его, у меня все работает отлично. Моя проблема в том, что он доставляет события со стратосферной скоростью, и это определенно разряжает батарею. Поэтому я использую решение потока. - person Hoconosc; 12.10.2012
comment
Хм, возможно, вместо того, чтобы использовать сенсорный материал, вы могли бы напрямую считывать ориентацию через getResources().getConfiguration().orientation каждые 2 секунды. См.: stackoverflow.com/questions/2795833/ - person Ridcully; 12.10.2012
comment
Мне нужен наклон в градусах, а не в портретной или альбомной ориентации телефона. - person Hoconosc; 12.10.2012
comment
Одна новая идея — почему бы не постоянно слушать события и просто пропускать их, если они новее 1 или 2 секунд? И то, что делает большинство людей, так как значения сильно различаются, - это вычисление некоторого среднего значения из последних n событий. В документе Sensor API Doc есть даже пример кода. - person Ridcully; 12.10.2012
comment
Этот способ не экономит заряд батареи, потому что onSensorChanged вызывается более 20 раз в секунду (даже если тело метода пропускается с использованием условия). На данный момент я думаю, что решение с протектором более экономично для батареи. - person Hoconosc; 12.10.2012

Я не знал, что датчик отслеживает события, но и не удивлен, так как видел подобное поведение в Locationlistener для сетевого провайдера.

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

удачи.

person Luis    schedule 13.10.2012
comment
Проблема в том, что если я оставлю датчик зарегистрированным, не отменяя регистрацию и не перерегистрируя его каждые X секунд, onSensorChanged будет вызываться более 20 раз в секунду. Среднее значение может быть хорошим для точности, но не для батареи. Я только пытался правильно прочитать первое значение и пропустить другие (и делать это каждые X секунд). Я думаю, что работающий поток больше экономит заряд батареи, чем оставит датчик зарегистрированным, а onSensorChanged запущенным > 20 раз в секунду. - person Hoconosc; 13.10.2012