Акселерометра Android не работает, когда экран выключен
Я разрабатываю приложение для окончательной диссертации по информатике, и мне нужно собирать и регистрировать данные акселерометра. Мне нужно приобрести его в течение всего дня, поэтому есть серьезные ограничения батареи (например, я не могу оставить экран включенным). Кроме того, это не рыночное целевое приложение, поэтому вполне приемлемо сделать некоторые серьезные взломы, даже низкоуровневое кодирование C/C++, если это необходимо.
хорошо известно, что на многих устройствах слушателей для акселерометра события перестают генерировать события, когда экран гаснет (некоторые ссылки, касающиеся этой проблемы:http://code.google.com/p/android/issues/detail?id=3708,акселерометр перестает доставлять образцы, когда экран выключен на Droid / Nexus One даже с WakeLock). Я тщательно искал некоторые альтернативы, некоторые из них включают обходные пути, которые не работают для моего устройства (LG P990, stock ROM).
Так что же происходит это:
При регистрации прослушивателя событий для датчик акселерометра android в Службе, он отлично работает, пока экран не выключен. Я уже пытался зарегистрировать eventListener на сервисе, на IntentService, пытался приобрести WakeLocks. Что касается wakelocks, я могу проверить, что Служба все еще работает, наблюдая за выходом LOGcat, но, похоже, акселерометр переведен в спящий режим. Одним из обходных путей, представленных в некоторых ссылках, является отмена регистрации и повторная регистрация прослушивателя событий периодически с помощью потока IntentService как в этом фрагменте кода ниже
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
protected void onHandleIntent(Intent intent) {
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
synchronized (this) {
boolean run = true;
while (run){
try {
wait(1000);
getLock(AccelerometerService.this).acquire();
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
Log.d("Accelerometer service", "tick!");
} catch (Exception e) {
run = false;
Log.d("Accelerometer service", "interrupted; cause: " + e.getMessage());
}
}
}
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," + event.values[2]);
}
что действительно заставляет onSensorChange вызываться каждый раз, когда мы отменяем регистрацию/регистрируем слушателя. Проблема в том, что полученное событие содержит всегда одни и те же значения, независимо от меня встряхивания устройства.
Итак, в основном мои вопросы: (медведь со мной, я почти заканчиваю :P)
возможно ли иметь доступ низкого уровня (подход C / C++) к оборудованию акселерометра Без регистрации в прослушивателе событий?
есть ли другой обходной путь или взломать?
может ли кто-нибудь с более современным телефоном любезно проверить, сохраняется ли проблема в прошивке 3.0 и выше?
[обновление]
к сожалению, это, кажется, ошибка с некоторыми мобильными телефонами. Подробнее в моем ответе.
6 ответов:
в принципе, это проблема с моим телефоном. Другие пользователи сообщили, что это также происходит с их телефонами, от разных брендов, но той же версии Android. Другие люди не имеют никаких проблем вообще-решительно указывая, что это не проблема с фондовой версией android, но от реализации каждой компании для своих драйверов оборудования.
Мне нужны постоянные данные акселерометра, и у меня нет ключа для измерения этих данных - у меня есть Arduino с Bluetooth и акселерометр, поэтому я мог бы реализовать это решение. Поэтому я решил, что временное решение для моего мобильного телефона до экрана (серым) и игнорировать расход батареи. Позже я буду выполнять тесты для использования батареи с помощью другого телефона android, который работает с выключенным экраном.
дополнительная информация об ошибке
Я исследовал и нашел сообщения от других пользователей Android, и я думаю, я понимаю то, что происходит. Библиотека libsensors.so который имеет драйверы для датчиков телефона не разработан Google, но каждым поставщиком мобильных телефонов-конечно, потому что каждый мобильный телефон имеет свое собственное специфическое оборудование. Google предоставляет только файл заголовка C, чтобы разработчики знали, что они должны реализовать. В некоторых реализациях для этих драйверов разработчики просто выключают акселерометр, когда экран гаснет, тем самым предотвращая прослушивание событий датчика для получения новых события.
Я также протестировал это с CyanogenMod RC7.2, но это тоже не сработало, потому что драйверы акселерометра оригинальны от LG.
электронной почте обменялись с представителями HR-департамента компании LG
Я отправил электронное письмо разработчикам LG P990 и, наконец, получил некоторые конкретные ответы! Это может быть очень полезно для некоторых людей, как я, которые испытывают эти проблемы с Android. Я написал следующий вопрос
Здравствуйте! Я развивая свою диссертацию по информатике и в настоящее время я я извлекаю данные из аппаратного акселерометра. На данный момент, я узнал что акселерометры не отправляют события, когда экран выключен, поэтому даже когда я хватаю wakelock из одной из моих программ, я могу убедитесь, что моя программа все еще работает (через выход LOGcat), но нет акселерометр событие выходит. Я должен приглушить свой экран (который я не могу себе позволить, батарея разряжается слишком быстро), чтобы начать получать события акселерометра снова. Я также попытался получить доступ к нему через родной C код, регистрирующий на акселерометре события но результат был тот то же самое, акселерометр не бросал никаких значений, хотя я был вращая свое устройство. Поэтому мне было интересно, могу ли я иметь прямой доступ к оборудованию, с машинным кодом, без регистрации в слушатель. Это возможно? Если да, не могли бы вы любезно дать еще немного совет? Я бы очень признателен за любую помощь! Мартин
за что я получил такой ответ:
дорогой Мартин, мы получили ответ от Дэва. Команда. Они сказали, что вы не удается получить событие акселерометра, пока экран телефона выключен. Потому что Хэл слой не реализовать файловую систему sysfs путь, чтобы получить Ч/Ш мероприятия, такие как акселерометр и нет публичного API для получения события. Спасибо. Лучший С уважением. (Шон Ким)
затем я отправил электронное письмо обратно, сказав, среди прочего, что я считаю это ошибкой, так как у вас должен быть доступ для всего оборудования при приобретении блокировки пробуждения:
[...] Я задал этот вопрос, потому что у меня есть некоторые друзья, которые также имеют Android телефоны с той же версией пряника, но от других бренды мобильных телефонов, и некоторые из них сообщили, что они получают события от акселерометр, когда экран выключен. Я читал на некоторых форумы, что эта ошибка-Я считаю это ошибкой, так как когда я приобретаю Wakelock я ожидал бы иметь некоторую обработку происходит-зависит от этот драйверы датчиков, которые поставщики реализуют для своих мобильных телефонов. Есть есть ли вероятность того, что эти драйверы могут быть обновлены или это ошибка будет исправлена в какой-то момент? Это помогло бы мне чрезвычайно с моей текущая работа.[ ..]
и тогда я получил такой ответ:
насколько мне известно от Dev. Команда, это не баг. Это безграничное количество этот телефон из-за H / W архитектуры. Мы должны перестроить Хэл архитектура и драйвер устройства Поддержите Ваш запрос. Но, как вы знаю, что это слишком сложно из-за отсутствия ресурсов. Мы пытаемся помогите вам со всеми нашими усилиями, но мы не можем поддержать вашу просьбу, как я упомянутый. (Шон Ким)
таким образом, они, по - видимому, знают об этом, но не пытаются исправить это, потому что либо они не думают, что это ошибка, которую я по - прежнему считаю логическим недостатком, либо у них нет времени/ресурсов для ее исправления.
итог Если у вас есть мобильный телефон, который не отправляет события акселерометра с выключенным экраном, попробуйте обновить прошивку. Если это не решает, и вы действительно хотите сделать какой-то серьезный взлом, повторно реализовать свой аппаратный уровень-подсказка: это, вероятно, что-то делать libsensors.so.
Я не уверен, что это действительно поможет вам, но я нашел работу вокруг (не уверен, насколько хорошо, если это поможет экономии батареи, хотя).
С помощью bash у меня есть пока цикл cat-ing
/sys/devices/virtual/accelerometer/accelerometer/acc_file, и когда я выключаю экран с помощью кнопки питания выход продолжается, но заморожен. (У меня был sshd, работающий в chroot, следовательно, возможность видеть его.)однако, в гулкой
0 > /sys/devices/platform/msm_fb.196609/leds/lcd-backlight/brightness. Экран выключается, и выход является непрерывным.это на a SGH-T589W, работает под управлением android версии 2.3.6.
я применил PARTIAL_WAKE_LOCK и он работал как шарм для меня. Протестировано на ОС 5.0, 6.0 и 7.0. Вот мой код для получения и освобождения wake lock. Будьте осторожны, это увеличило дренаж батареи, поэтому приобретайте и выпускайте его разумно.
public void acquireWakeLock() { final PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); releaseWakeLock(); //Acquire new wake lock mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PARTIAL_WAKE_LOCK"); mWakeLock.acquire(); } public void releaseWakeLock() { if (mWakeLock != null && mWakeLock.isHeld()) { mWakeLock.release(); mWakeLock = null; } }Ref:https://developer.android.com/training/scheduling/wakelock.html#cpu
Я работаю над sdk прогнозирования, который использует данные датчиков устройства (акселерометр/гироскоп) и предсказывает события пользователя. Я испытал ту же проблему.
я столкнулся с аналогичными проблемами при запуске Samsung Nexus Android 4.0.2 использование других системных служб, которые останавливаются / приостанавливаются, когда экран выключен, даже если
PARTIAL_WAKE_LOCKприобретается. Мое решение было использоватьSCREEN_DIM_WAKE_LOCKв:lockStatic = mgr.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,NAME);было бы гораздо лучше, чтобы экран полностью выключен, но, по крайней мере, это решение работает, хотя было бы еще лучше, если бы я мог ограничить использование
SCREEN_DIM_WAKE_LOCKтолько для тех устройств / ОС, которые требуют его.
Я не хочу вас разочаровывать, но некоторые устройства просто не поддерживают acceleromet, пока они находятся в спящем режиме. Вы можете проверить любое приложение для похудения шагомера в магазине большинство из них явно заявляют, что это не будет работать на некоторых устройствах.
если опция частичной блокировки пробуждения недоступна для вашего телефона, это означает, что драйвер для датчика имеет
early_suspendвключено.есть два варианта.
1: Отключение
EARLY_SUSPENDдрайвера2: Добавьте флаг времени выполнения, который может
enable/disable early_suspendфункции на уровне драйвера.ex. cat / sys / module / earlysuspend / sensor 1/0
ИМО второй вариант должен был быть с самого начала.
Comments