Android акселерометр не работает при выключенном экране
Я разрабатываю приложение для моей последней диссертации по информатике, и мне нужно собирать и регистрировать данные акселерометра. Мне нужно приобрести его на целый день, поэтому есть серьезные ограничения батареи (например, я не могу оставить экран включенным). Кроме того, это не приложение, ориентированное на рынок, поэтому вполне приемлемо сделать серьезный взлом, даже низкоуровневое C / C ++-кодирование, если это необходимо.
Хорошо известно, что на многих устройствах слушатели событий акселерометра перестают генерировать события, когда экран выключается (некоторые ссылки, касающиеся этой проблемы:http://code.google.com/p/android/issues/detail?id=3708 , Акселерометр перестает доставлять образцы, когда на Droid / Nexus One экран выключен, даже с WakeLock). Я тщательно искал некоторые альтернативы, некоторые из них включают обходные пути, которые не работают для моего устройства (LG P990, стандартное ПЗУ).
Итак, что происходит так: когда вы регистрируете прослушиватель событий для датчика акселерометра Android в Сервисе, он работает нормально, пока экран не выключится. Я уже пытался зарегистрировать eventListener на Сервисе, на IntentService, пытался получить 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 и выше?
[ОБНОВИТЬ]
К сожалению, похоже, что это ошибка некоторых мобильных телефонов. Более подробно в моем ответе.