Датчик приближения не работает с выключенным экраном?

Hy,

У меня проблема с датчиком приближения. Когда я кладу на него палец, я хочу выключить экран, а когда я беру палец, я хочу включить экран. Я успешно выполнил отключение, но когда я убираю палец с сенсора, похоже, он не выполняет метод onSensorChanged. Вот его код:

public void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD && distance < event.sensor.getMaximumRange());
        boolean isValidCallState = false;

        if (callsInfo != null) {
            for (SipCallSession callInfo : callsInfo) {
                int state = callInfo.getCallState();
                isValidCallState |= ((state == SipCallSession.CallState.CONFIRMED)
                        || (state == SipCallSession.CallState.CONNECTING)
                        || (state == SipCallSession.CallState.CALLING) || (state == SipCallSession.CallState.EARLY && !callInfo
                        .isIncoming()));
            }
        }
        if (isValidCallState && active) {
            Log.e("", "turn off");
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
            lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;

            getWindow().setAttributes(lp);
            lockOverlay.show();
        } else {
            Log.e("", "turn on");
            WindowManager.LayoutParams lp = getWindow().getAttributes();

            lp.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
            lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
            getWindow().setAttributes(lp);
        }
        Log.e("", "turn ???"); // --> does not print this when releasing the sensor
    }

Любые идеи? Спасибо.


person Andrei    schedule 31.01.2012    source источник


Ответы (2)


Я нашел ответ на свой вопрос и сумел разобраться в основном протоке датчика приближения.

Во-первых, есть 2 способа обработать датчик приближения: 1. Сделать блокировку PROXIMITY_SCREEN_OFF_WAKE_LOCK. Из того, что я читал, это каким-то образом скрытая константа, используемая android, которая имеет значение 32 (по крайней мере, на данный момент - может или не может быть изменен в будущих версиях). Если эта блокировка завершится успешно, датчик приближения будет вести себя так, как если бы вы разговаривали.

try {
                    Method method = powerManager.getClass().getDeclaredMethod(
                            "getSupportedWakeLockFlags");
                    int supportedFlags = (Integer) method.invoke(powerManager);
                    Field f = PowerManager.class.getDeclaredField("PROXIMITY_SCREEN_OFF_WAKE_LOCK");
                    int proximityScreenOffWakeLock = (Integer) f.get(null);
                    if ((supportedFlags & proximityScreenOffWakeLock) != 0x0) {
                        proximityWakeLock = powerManager.newWakeLock(proximityScreenOffWakeLock,
                                "com.voalte.CallProximity");
                        proximityWakeLock.setReferenceCounted(false);
                    }

                } catch (Exception e) {
                }
  1. Зарегистрируйте слушателя для Sensor. В этом случае действия датчика приближения должны обрабатываться в методе onSensorChanged (можно задать screenBrigthness).

Примечание:

  1. Когда экран выключен, вызывается onPause.
  2. Если вы используете первый метод, вам следует подумать о наличии резервной копии на случай, если PROXIMITY_SCREEN_OFF_WAKE_LOCK не может быть установлен. Поэтому я рекомендую попробовать создать блокировку в onStart и onResume, чтобы проверить ее на значение null. Если не null, получить блокировку, в противном случае зарегистрируйте слушателя для датчика.
  3. В onSensorChanged я установил screenBrightness на BRIGHTNESS_OVERRIDE_OFF, при закрытии сенсора и при включении я установил screenBrightness на BRIGHTNESS_OVERRIDE_FULL и / или BRIGHTNESS_OVERRIDE_NONE, но экран не включился. Таким образом, обходной путь заключался в том, чтобы сделать черный макет, который по умолчанию невидим, чтобы он был видимым и занимал весь экран.

Надеюсь, это кому-то поможет.

person Andrei    schedule 02.02.2012

Я предполагаю, что ваша программа - это Activity, которая запускается «на экране»?

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

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

Я не уверен, что этот «ответ» действительно поможет вам, но вы можете понять, что искать.

person varesa    schedule 31.01.2012
comment
Я пробовал сделать несколько замков. Сначала я попробовал: PARTIAL_WAKE_LOCK, затем PROXIMITY_SCREEN_OFF_WAKE_LOCK и значение 32, но ничего не сработало :( - person Andrei; 31.01.2012