简体   繁体   English

以编程方式禁用 Android 上的屏幕开/关磁传感器

[英]Programmatically disable the screen on/off magnetic sensor on Android

Several Android devices famously the Nexus series have a magnetic sensor that is NOT the android.hardware.Sensor.TYPE_MAGNETIC_FIELD used exclusively to turn the screen ON/OFF automatically using phone cases that have a small magnet inside them.一些著名的 Nexus 系列 Android 设备有一个磁性传感器,而不是android.hardware.Sensor.TYPE_MAGNETIC_FIELD专门用于使用内部有小磁铁的手机壳自动打开/关闭屏幕。

On my application, I'm using magnet detection using android.hardware.Sensor.TYPE_MAGNETIC_FIELD and the SensorManager to detect user touches the phone in a case with some magnets inside.在我的应用程序中,我使用android.hardware.Sensor.TYPE_MAGNETIC_FIELDSensorManager使用磁铁检测来检测用户在内部有磁铁的情况下触摸手机。

The code works without issues, the problem is that it's extremely easy on those devices to accidentally trigger the screen ON/OFF sensor thou, turning off the screen.该代码可以正常工作,问题在于这些设备非常容易意外触发屏幕开/关传感器,关闭屏幕。

I've tried:我试过了:

  • android:keepScreenOn="true" on the XML android:keepScreenOn="true"在 XML 上
  • using the permission android.permission.WAKE_LOCK and acquiring a wake-lock via PowerManager .使用权限android.permission.WAKE_LOCK并通过PowerManager获取唤醒锁。

Both without success.两者都没有成功。

Is there a way to temporarily disable this sensor while my activity is resumed?有没有办法在我的活动恢复时暂时禁用此传感器?

The keepScreenOn = true in manifest also doesn't work here as the action of hall effect sensor is same as pressing power button.清单中的 keepScreenOn = true 在这里也不起作用,因为霍尔效应传感器的动作与按下电源按钮相同。

Here, I offer a work-around that I have tested.在这里,我提供了一个我已经测试过的解决方法。 In this approach you display your activity regardless of hall-effect sensor locking the device and turning of the display.在这种方法中,无论霍尔效应传感器是否锁定设备并转动显示器,您都可以显示您的活动。

Before beginning the unlocking action在开始解锁动作之前

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

credits for above code - https://stackoverflow.com/a/45951927/9640177以上代码的积分 - https://stackoverflow.com/a/45951927/9640177

Also make sure to add Permissions还要确保添加权限

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

Setting these flags will make sure that your window will be visible above lockscreen.设置这些标志将确保您的窗口在锁定屏幕上方可见。

Now, listen for ACTION_SCREEN_OFF intent.现在,监听 ACTION_SCREEN_OFF 意图。 To do this add a broadcast receiver that listens for this intent broadcasted by the system.为此,添加一个广播接收器,用于侦听系统广播的此意图。 You need to register the receiver locally.您需要在本地注册接收器。 (stackoverflow.com/a/9478013/9640177) in manifest (stackoverflow.com/a/9478013/9640177)在清单中

    <receiver android:name=".receiver">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF"/>
        </intent-filter>
    </receiver>

Receiver class接收器类

public class receiver extends BroadcastReceiver {
  MyActivity activity;
  receiver(MyActivity activity){
    this.activity = activity;
  }
  @Override
  public void onReceive(final Context context, Intent intent) {
    activity.turnOnScreen();
  }
}

Inside activity内部活动

 // register receiver
 ...
 IntentFilter screenStateFilter = new IntentFilter();
    screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
    receiver r = new receiver(MyActivity.this);
    registerReceiver(r, screenStateFilter);
 ...
// function to turn on display
public void turnOnScreen(){
    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "my:Tag");
    wakeLock.acquire();
    wakeLock.release();
}

credit - https://stackoverflow.com/a/44706632/9640177 This will turn the display on.信用 - https://stackoverflow.com/a/44706632/9640177这将打开显示。

Don't forget to remove these flags after your activity has done the job and does not require to be in forefront.不要忘记在您的活动完成工作后删除这些标志,并且不需要排在最前面。

getWindow().removeFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

This will make your window disappear from lock-screen and make the application function normally.这将使您的窗口从锁定屏幕中消失并使应用程序正常运行。

Hope this helps.希望这可以帮助。

the most pragmatic solution to the problem might be ...解决这个问题最务实的办法可能是……

to disable the smart cover feature physically rather than by software.以物理方式禁用智能封面功能,而不是通过软件。

eg.例如。 take a razorblade and tweezers and then remove the magnet.拿一把剃须刀和镊子,然后取下磁铁。

... or simply get another cover without a magnet. ... 或者干脆换一个没有磁铁的盖子。

alternatively, file a bug against drivers/input/lid.c .另外,文件中的错误drivers/input/lid.c

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

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