3

嗨,

我有一个与接近传感器有关的问题。当我将手指放在上面时,我想关闭屏幕,当我拿手指时,我想打开屏幕。我成功地完成了关闭部分,但是当我将手指从传感器上移开时,它似乎没有执行 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
    }

有任何想法吗?谢谢。

4

2 回答 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 中实例化锁以检查它是否为空。如果不为空,则获取锁,否则为传感器注册监听器。
  3. 在 onSensorChanged 中,我将 screenBrightness 设置为 BRIGHTNESS_OVERRIDE_OFF,当覆盖传感器和释放时,我将 screenBrightness 设置为 BRIGHTNESS_OVERRIDE_FULL 和/或 BRIGHTNESS_OVERRIDE_NONE,但它没有打开屏幕。因此,一种解决方法是制作一个默认设置为不可见的黑色布局,使其可见并占据全屏。

希望这对某人有帮助。

于 2012-02-02T12:14:00.237 回答
0

我猜你的程序是一个“在屏幕上”运行的活动?

我对这个主题了解不多,但根据我在android上阅读的一些文字,我认为android会在屏幕关闭时暂停/关闭应用程序。

您要么必须阻止这种暂停,要么在后台服务中运行您的应用程序。但我不知道服务是否可以以相同的方式读取传感器。

我不确定这个“答案”是否真的会帮助你,但你可能会知道要搜索什么。

于 2012-01-31T09:15:42.050 回答