Я разрабатываю приложение для моей выпускной диссертации по информатике, и мне нужно собрать и зарегистрировать данные акселерометра. Мне нужно приобрести его на целый день, поэтому есть серьезные ограничения по батарее (, например, я не могу оставить экран включенным). Кроме того, это не ориентированное на рынок приложение, поэтому вполне приемлемо заняться серьезным взломом, даже низкоуровневым кодированием 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 и выше?
[ОБНОВЛЕНИЕ]
К сожалению, это ошибка некоторых мобильных телефонов. Подробнее в моем ответе.