问题
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
}
Any ideas? Thanks.
回答1:
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) {
}
- Register a listener for the Sensor. In this case the proximity sensor actions must be handled in the onSensorChanged method(screenBrigthness can be set).
Note:
- When the screen is turned off, the onPause is called.
- 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.
- 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.
回答2:
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.
来源:https://stackoverflow.com/questions/9076834/proximity-sensor-not-working-with-screen-turned-off