Акселерометр перестает доставлять образцы, когда на Droid / Nexus One экран выключен, даже с WakeLock - PullRequest
24 голосов
/ 27 января 2010

У меня есть некоторый код, который расширяет службу и записывает показания датчика акселерометра SensorChanged (событие SensorEvent) на Android. Я хотел бы иметь возможность записывать показания этих датчиков, даже когда устройство выключено (я осторожен с временем работы от батареи, и это становится очевидным, когда оно работает). Пока экран на логи работает нормально на 2.0.1 Motorola Droid и 2.1 Nexus One.

Однако, когда телефон переходит в спящий режим (нажатием кнопки питания), экран выключается и события onSensorChanged перестают доставляться (проверяется с помощью сообщения Log.e каждый раз, когда вызывается onSensorChanged).

Служба получает wakeLock, чтобы обеспечить его работу в фоновом режиме; но, похоже, это не имеет никакого эффекта. Я перепробовал все различные PowerManager. следы, но ни один из них не имеет значения.

_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
_WakeLock.acquire();

Поступали противоречивые сообщения о том, можете ли вы на самом деле получать данные с датчиков, когда экран выключен ... Кто-нибудь имел опыт работы с этим на более современной версии Android (Eclair) и оборудовании?

Это, кажется, указывает на то, что он работал в Cupcake: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5

PS: Точно такой же код работает, как и предполагалось в 1.5 на G1. Регистрация продолжается, когда экран выключается, когда приложение находится в фоновом режиме и т. Д.

Ответы [ 5 ]

9 голосов
/ 30 января 2010

Мы пришли к выводу, что это началось с 2.0.1. Это кажется преднамеренным, возможно, частью увеличения срока службы батареи, которое рекламировалось как особенность. У нас был рабочий толчок, чтобы разбудить или разблокировать 2.0, затем он сломался при обновлении, и мы не смогли найти какой-либо обходной путь. ; '(Неважно, удерживается ли частичная блокировка ЦП, которая, как предполагается, всегда препятствует сну ЦП. Из того, что я видел, отладка журналирования через USB, иногда появляется упоминание об изменениях в прослушивателе датчиков во время сна.

Пользователь опубликовал обходной путь, который, как он утверждал, работает на устройствах Motorola - https://sites.google.com/a/bug-br.org.br/android/technical-documents

Я протестировал обходной путь, придумав следующий код из учебного пособия и некоторую ручную ревизию (в представленном учебном пособии есть несколько «ошибок»):

public class ShakeWakeupService extends Service implements SensorEventListener{
     private Context mContext;
     SensorManager mSensorEventManager;
     Sensor mSensor;

     // BroadcastReceiver for handling ACTION_SCREEN_OFF.
     public BroadcastReceiver mReceiver = new BroadcastReceiver() {

         @Override
         public void onReceive(Context context, Intent intent) {
             // Check action just to be on the safe side.
             if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 Log.v("shake mediator screen off","trying re-registration");
                 // Unregisters the listener and registers it again.
                 mSensorEventManager.unregisterListener(ShakeWakeupService.this);
                 mSensorEventManager.registerListener(ShakeWakeupService.this, mSensor,
                     SensorManager.SENSOR_DELAY_NORMAL);
             }
         }
     };

         @Override
         public void onCreate() {
           super.onCreate();
           Log.v("shake service startup","registering for shake");
           mContext = getApplicationContext();
             // Obtain a reference to system-wide sensor event manager.
           mSensorEventManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
             // Get the default sensor for accel
           mSensor = mSensorEventManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
             // Register for events.
           mSensorEventManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);

             // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
             // code be called whenever the phone enters standby mode.
           IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
           registerReceiver(mReceiver, filter);
     }

     @Override
     public void onDestroy() {
        // Unregister our receiver.
         unregisterReceiver(mReceiver);
         // Unregister from SensorManager.
         mSensorEventManager.unregisterListener(this);
     }

     @Override
     public IBinder onBind(Intent intent) {
         // We don't need a IBinder interface.
  return null;
     }

 public void onShake() {
         //Poke a user activity to cause wake?
     }
     public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //not used right now
            }
            //Used to decide if it is a shake
            public void onSensorChanged(SensorEvent event) {
                    if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return;
                  Log.v("sensor","sensor change is verifying");
            }
      }

Обходной путь работает для меня, но не будет работать, когда у меня запущен screebl, и эта функция, которую многие мои пользователи действительно хотят работать в сочетании с тем, что я разрабатываю.

1 голос
/ 17 ноября 2011

Использование SCREEN_DIM_WAKE_LOCK у меня сработало на HTC EVO ..

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
_WakeLock.acquire();
1 голос
/ 24 мая 2010

Только что обновил мой Nexus One с помощью ПЗУ FROYO FRF50, которое работало в интернете в течение последних нескольких дней, и кажется, что сенсоры теперь снова работают, когда экран выключен, если у вас есть PARTIAL_WAKELOCK. Я не знаю, удастся ли это сделать официальной сборке, хотя, насколько я понимаю, она основана на официальной сборке, которую получили некоторые пользователи N1. Так что, возможно, они передумали (еще раз) и снова включили датчики, когда телефон заблокирован. Скрестив пальцы.

Конечно, они могли бы просто пойти и отключить их снова в 2.2-r1, кто знает ...

0 голосов
/ 24 октября 2010

Существует альтернативное решение (своего рода), в котором экран всегда включен, используя:

Settings.System.putInt (getContentResolver (), Settings.System.SCREEN_OFF_TIMEOUT, -1);

Но это не мешает пользователю принудительно выключать экран нажатием кнопки питания, после чего поток событий датчика останавливается. Вам также нужно разрешение WRITE_SETTINGS, чтобы это работало.

Обходной путь перерегистрации событий датчиков не работает на Droid Eris, который работает под управлением Android 2.1 и не ожидает обновления. Я использовал следующее, хотя, кажется, работает. Вместо отмены регистрации и повторной регистрации этот подход снова включает экран, когда пользователь выключает его, хотя он снова включается затемненным. В следующем коде обработчик - это просто простой обработчик, созданный в Activity (т. Е. Handler handler = new Handler ();), а mTurnBackOn - это WakeLock, инициализированный нулем.

public BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
            // Turn the screen back on again, from the main thread
            handler.post(new Runnable() {
            public void run() {
            if(mTurnBackOn != null)
                mTurnBackOn.release();

                mTurnBackOn = mPwrMgr.newWakeLock(
                    PowerManager.SCREEN_DIM_WAKE_LOCK |
                        PowerManager.ACQUIRE_CAUSES_WAKEUP,
                    "AccelOn");
                mTurnBackOn.acquire();
            }});
        }
    }
};
0 голосов
/ 10 сентября 2010

Похоже, что это проблема с прошивкой 2.1, мне необходимо исправить это, но мне нужно работать со всеми возможными обходными путями, чтобы охватить все версии.

Я составил список телефонов и прошивок, которые работают / не работают / работают с перебоями, чтобы мы могли либо протестировать телефон или прошивку.

http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/

Если у вас есть новый телефон, которым вы можете обновить список, сообщите мне.

...