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

标签 java android kotlin android-wake-lock

一些著名的 Nexus 系列 Android 设备有一个磁传感器,它不是 android.hardware.Sensor.TYPE_MAGNETIC_FIELD 专门用于使用带有小磁铁的手机壳自动打开/关闭屏幕在他们里面。

在我的应用程序中,我使用 android.hardware.Sensor.TYPE_MAGNETIC_FIELDSensorManager 进行磁铁检测,以检测用户在带有一些磁铁的情况下触摸手机里面。

代码运行没有问题,问题是在这些设备上非常容易意外触发屏幕开/关传感器,从而关闭屏幕。

我试过:

  • android:keepScreenOn="true" 在 XML 上
  • 使用权限 android.permission.WAKE_LOCK 并通过 PowerManager 获取唤醒锁。

都没有成功。

有没有办法在我恢复 Activity 时暂时禁用此传感器?

最佳答案

list 中的 keepScreenOn = true 在这里也不起作用,因为霍尔效应传感器的 Action 与按下电源按钮相同。

在这里,我提供了一个我已经测试过的解决方法。在这种方法中,无论霍尔效应传感器锁定设备和显示器转动如何,您都可以显示您的 Activity 。

在开始解锁 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);

以上代码的学分 - https://stackoverflow.com/a/45951927/9640177

还要确保添加权限

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

设置这些标志将确保您的窗口在锁定屏幕上方可见。

现在,监听 ACTION_SCREEN_OFF Intent 。为此,添加一个广播接收器来监听系统广播的此 Intent 。您需要在本地注册接收器。 (stackoverflow.com/a/9478013/9640177) 在 list 中

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

接收类

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

内部 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();
}

信用 - https://stackoverflow.com/a/44706632/9640177 这将打开显示屏。

不要忘记在您的 Activity 完成工作并且不需要排在最前面之后删除这些标志。

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);

这将使您的窗口从锁定屏幕上消失并使应用程序正常运行。

希望这对您有所帮助。

关于java - 以编程方式禁用 Android 上的屏幕开/关磁传感器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43206734/

相关文章:

android - 找不到变量:在构建时 react

android - 如何从 Assets 文件夹或原始文件夹在android中播放视频?

android - 这个集合添加 fragment 代码块可以变得更简单吗(Kotlin)

android - 如何在Android Studio中无缝循环播放视频

java - 根据类型创建java对象

Java 8 类来表示时间间隔

java - 在 Java 中初始化二维数组

java - 如何使用 Java 中的 POI 在不同列上写入现有的 Excel (*.xlsx) 文件?

android - 检查数据连接是否为 "ticked"

spring-boot - 如何使用Jackson和java.time解析不同的ISO日期/时间格式?