Получете само 1 събитие от сензора

Опитвам се да получа само 1 събитие от сензора за ориентация.

Моят код е:

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

След това в нишка на всеки 1000ms правя:

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
Има getOrientation метод или подобен в API за получаване на наклона на телефона (ще го потърся по-късно) и публикувайте тук, ако не можете да го намерите. - 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