当面部靠近屏幕时,在Android上编程关闭屏幕

28

我的应用是一个拨号器,当用户将手机靠近头部时,我需要关闭屏幕并防止点击控件,就像原生的安卓拨号器行为一样。我需要使用哪个API级别,并如何以正确的方式执行此操作?


2
可能是 android: turn off screen when close to face 的重复。 - kotucz
4个回答

52

我通过反汇编一个非常著名的VoIP应用程序找到了解决方案。在关闭传感器时,按下按钮1后,此功能将禁用屏幕和硬件键。按下按钮2后,该功能将被关闭。

此外,此功能需要权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

活动。试试看。

public class MainActivity extends Activity {

    private Button button1;
    private Button button2;
    private PowerManager powerManager;
    private PowerManager.WakeLock wakeLock;
    private int field = 0x00000020;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            // Yeah, this is hidden field.
            field = PowerManager.class.getClass().getField("PROXIMITY_SCREEN_OFF_WAKE_LOCK").getInt(null);
        } catch (Throwable ignored) {
        }

        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(field, getLocalClassName());

        setContentView(R.layout.main);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        button1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(!wakeLock.isHeld()) {
                    wakeLock.acquire();
                }
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(wakeLock.isHeld()) {
                    wakeLock.release();
                }
            }
        });
    }
}

4
一个小修正:您应该使用 PowerManager.class 而不是 PowerManager.class.getClass() - Muzikant
1
不支持三星Duos、Moto E和Moto G第三代。 - Pararth
在我的LGE Nexus 4 - Android v.4.3 (API:18)上运行良好,尽管官方文档说PROXIMITY_SCREEN_OFF_WAKE_LOCK标志是在API 21中添加的(https://developer.android.com/reference/android/os/PowerManager)! - Astrogator
那是什么应用程序? - james04
@james04 这是 Skype。 - Solkin
显示剩余3条评论

3
以下代码展示了如何使用接近传感器:
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mProximity;

 @Override
 public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Get an instance of the sensor service, and use that to get an instance of
// a particular sensor.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
 }

 @Override
 public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
 }

 @Override
  public final void onSensorChanged(SensorEvent event) {
   float distance = event.values[0];
// Do something with this sensor data.
   }

 @Override
 protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
 }

 @Override
  protected void onPause() {
// Be sure to unregister the sensor when the activity pauses.
super.onPause();
mSensorManager.unregisterListener(this);
 }}

尝试使用此链接来使用接近传感器,当面部靠近屏幕时关闭屏幕。希望这能帮到你。

1
是的,这将向我发送很多事件,但我不知道如何关闭屏幕... 在链接的回答中只使用了私有的Android API。 - Solkin
我不明白OP为什么需要加速度计。他更有可能对接近传感器的事件感兴趣。 - Michael
1
谢谢,但是... 这只是传感器监听器。我需要禁用屏幕。 - Solkin
请查看此链接https://dev59.com/02kw5IYBdhLWcg3w6ewb,其中检查@hackbod发布的答案并尝试此代码`params.flags |= LayoutParams.FLAG_KEEP_SCREEN_OFF; params.screenBrightness = 0; getWindow().setAttributes(params)`希望这可以帮助到您。 - i.n.e.f
1
@i.n.e.f,没有FLAG_KEEP_SCREEN_OFF - suitianshi
显示剩余2条评论

2

如果您尝试Solkin发布的方法(使用wakelock)来解决问题,很多设备的CPU使用率会变高。这是Android设备中的一个错误。

为了避免任何问题,您应该使用onSensorChanged事件并显示黑屏。


1
“只需显示黑屏以避免任何问题”?你的意思是,除了由于屏幕实际上仍然处于开启状态而引起的所有新问题之外? - Michael

0
最好的方法是使用DialogFragment,您可以显示一个黑色屏幕并将其关闭。
@Override
  public final void onSensorChanged(SensorEvent event) {
   float distance = event.values[0];
     if(distance <10f)
    showDialogFragment()
     else
    hideDialogFragment()

   }

在这种情况下,用户会触摸屏幕、收到通知等。因此,在通话时必须关闭屏幕。 - Solkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接