Акселерометр 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)

  1. возможно ли иметь низкоуровневый доступ (подход C/C++)к оборудованию акселерометра БЕЗ регистрации на событие слушатель?

  2. Есть ли другой обходной путь или хак?

  3. Может ли кто-нибудь с более-современным-телефоном проверить, сохраняется ли проблема в прошивке 3.0 и выше?

[ОБНОВЛЕНИЕ]

К сожалению, это ошибка некоторых мобильных телефонов. Подробнее в моем ответе.

68
задан Community 23 May 2017 в 12:17
поделиться