简体   繁体   English

接近传感器无法关闭屏幕?

[英]Proximity sensor not working with screen turned off?

Hy, 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. 我成功地完成了关闭部分,但是当我将手指从传感器上移开时,它似乎没有执行onSensorChanged方法。 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. 谢谢。

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. 首先,有两种方法可以处理接近传感器:1。锁定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). 从我读到的这个是某种方式是android使用的隐藏常量,其值为32(至少目前 - 在未来版本中可能会或可能不会更改)。 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. 注册Sensor的监听器。 In this case the proximity sensor actions must be handled in the onSensorChanged method(screenBrigthness can be set). 在这种情况下,接近传感器动作必须在onSensorChanged方法中处理(可以设置screenBrigthness)。

Note: 注意:

  1. When the screen is turned off, the onPause is called. 关闭屏幕时,会调用onPause。
  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. 如果你使用第一种方法,你应该考虑在不能设置PROXIMITY_SCREEN_OFF_WAKE_LOCK的情况下备份。 So I recommend to try and instantiate the lock in onStart and in onResume to check it against null. 因此,我建议尝试在onStart和onResume中实例化锁,以检查它是否为null。 If not null, aquire the lock, otherwise register listener for the sensor. 如果不为null,则获取锁定,否则为传感器注册侦听器。
  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. 在onSensorChanged中,我将screenBrightness设置为BRIGHTNESS_OVERRIDE_OFF,当覆盖传感器时和relesing时我将screenBrightness设置为BRIGHTNESS_OVERRIDE_FULL和/或BRIGHTNESS_OVERRIDE_NONE,但它没有打开屏幕。 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. 希望这对某人有帮助。

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. 我对这个主题了解不多,但根据我在android上阅读的一些文字,我认为当屏幕出现故障时,android会暂停/关闭应用程序。

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. 我不确定这个“答案”是否会对你有所帮助,但你可能会知道要搜索什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM