¿El sensor de proximidad no funciona con la pantalla apagada?

Hy,

I have a problem related to the proximity sensor. When I put the finger on it, I want to turn the screen off and when I take the finger, I want to turn the screen on. I successfully did the turning off part, but when I take the finger off the sensor, it does not seem to execute the onSensorChanged method. Here is the code for it:

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
    }

¿Algunas ideas? Gracias.

preguntado el 31 de enero de 12 a las 08:01

2 Respuestas

I found the answer to my question and managed to figure out the main flow of the proximity sensor.

First, there are 2 ways to handle the proximity sensor: 1. Make a lock on PROXIMITY_SCREEN_OFF_WAKE_LOCK. From what I read this is somehow a hidden constant used by android, that has the value 32(at least for the moment - might or might not be changed in future versions). If this lock succeeds, the proximity sensor, will behave as you are in a call.

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. Register a listener for the Sensor. In this case the proximity sensor actions must be handled in the onSensorChanged method(screenBrigthness can be set).

Nota:

  1. When the screen is turned off, the onPause is called.
  2. If u use the first method, u should consider to have also a back-up in case the PROXIMITY_SCREEN_OFF_WAKE_LOCK cannot be set. So I recommend to try and instantiate the lock in onStart and in onResume to check it against null. If not null, aquire the lock, otherwise register listener for the sensor.
  3. In the onSensorChanged I set the screenBrightness to BRIGHTNESS_OVERRIDE_OFF, when covering the sensor and when relesing I set the screenBrightness to BRIGHTNESS_OVERRIDE_FULL and/or BRIGHTNESS_OVERRIDE_NONE, but it didn't turn the screen on. So a workaround was to make a black layout that is set invisible by default, to be visible and occupy the full screen.

Hope this is of help for somebody.

Respondido 02 Feb 12, 16:02

I guess that your program is an Activity that runs "on the screen"?

I do not know much about this subject, but based on some text I have read on android, I think android pauses/closes apps when the screen goes down.

Either you would have to prevent this pausing, or run your app in a background service. But I dont know if services can read the sensora in the same way.

Im not sure if this "answer" will really help you, but you might get some idea what to search for.

Respondido el 31 de enero de 12 a las 13:01

I tried making some locks. First I tried: PARTIAL_WAKE_LOCK, then PROXIMITY_SCREEN_OFF_WAKE_LOCK and the 32 value, but none did work :( - Andrés

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.