在安卓系统中,以编程方式禁用屏幕开关磁传感器

7

一些Android设备,尤其是Nexus系列,具有一个磁性传感器,它不是专门用于通过内部带有小磁铁的手机壳自动开关屏幕的android.hardware.Sensor.TYPE_MAGNETIC_FIELD传感器。

在我的应用程序中,我使用android.hardware.Sensor.TYPE_MAGNETIC_FIELDSensorManager来检测用户是否触摸了带有一些磁铁的手机壳。

代码可以正常工作,问题是在这些设备上极易意外触发开/关屏幕的传感器,导致屏幕关闭。

我已经尝试过:

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

但两者都没有成功。

在我的活动恢复时,是否有一种方法可以暂时禁用此传感器?


据我所知,似乎谷歌没有提供访问“霍尔效应传感器”的API。 - aminography
我使用以下代码来保持屏幕常亮:getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - khalid3e
这个问题只出现在你的应用程序中吗?因为你正在尝试使用这个传感器。 - Mayank Kumar Chaudhari
@m__ 我并不想使用霍尔效应传感器,我们正在使用正常的Sensor.TYPE_MAGNETIC_FIELD来检测用户在公司出售的硬件上“轻敲”手机(它是一个门控制器,您可以轻敲它来打开门,因此里面包含一些磁铁),但由于另一个传感器有时会关闭屏幕,所以在门控制器上轻敲可能会关闭屏幕。 - Budius
好的。我理解保持屏幕常亮(keepScreenOn)也无法工作,因为另一个传感器产生的效果与手动按下屏幕锁定按钮相同。 - Mayank Kumar Chaudhari
2个回答

3
在清单中的keepScreenOn = true也无法在这里起作用,因为霍尔效应传感器的操作与按下电源按钮相同。在此,我提供了一个经过测试的解决方法。在这种方法中,您可以显示活动,而不管霍尔效应传感器是否锁定设备并关闭显示屏。
在执行解锁操作之前:
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意图。为此,添加一个广播接收器,该接收器侦听系统广播的这个意图。您需要在本地注册接收器。(stackoverflow.com/a/9478013/9640177) 在清单中

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

活动内部

 // 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 这将打开显示。

不要忘记在您的活动完成任务且不需要处于前台时删除这些标志。

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

这将使您的窗口从锁屏中消失,并使应用程序正常工作。
希望这能帮到您。

希望这对所有设备都适用,无论是已经root过的还是未root的。您需要在应用程序中添加10-20行额外的代码。我希望这将改善用户的体验。 - Mayank Kumar Chaudhari
演示 - https://play.google.com/store/apps/details?id=com.mayank.pdfviewer 在这种情况下,只有一次打开屏幕,因为上下文不同,打开屏幕可能不是理想的选择。 - Mayank Kumar Chaudhari
嗨m_,我故意让赏金自动颁发给你,并只颁发一半的赏金,因为这是一个比较可行的解决方法,我非常感谢你的努力,但这对我的特定情况不起作用。我真的需要禁用它,从@Kousic的答案中可以看出,这是不可能的真正答案。我的情况是,我们开发了一个SDK,其他开发人员将在其应用程序中使用它,因此所有那些在活动生命周期中注册广播的“黑客”都不是选项。 - Budius
谢谢你的回复。但是你能在不root设备的情况下操纵内核吗? - Mayank Kumar Chaudhari
我对ask的开发并不是很熟悉,只是感到好奇。 - Mayank Kumar Chaudhari
我不确定这是否解决了智能保护套的问题,但我注意到如果您使用SYSTEM_ALERT_WINDOW,则可能需要将WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY添加到您的标志中(来源)。 - Tokenyet

0

解决问题最实际的方法可能是...

通过物理方式禁用智能保护盖功能,而不是通过软件。

例如,使用剃须刀和镊子,然后移除磁铁。

... 或者直接购买另一个没有磁铁的保护盖。

或者,报告 drivers/input/lid.c 的错误。


我认为这就像是“如果眼睛有白内障,就摘掉眼睛”的做法。为什么不治疗它呢? - Mayank Kumar Chaudhari
@m__ 这取决于我们是在谈论一个单独的眼睛还是许多眼睛。如果他们同意,针对供应商ROM的错误报告可能是最好的解决方案。 - Martin Zeitler
你可能更喜欢这个。请尝试我的答案。它可以绕过这个问题。屏幕可能被锁定,但应用程序不会因为屏幕锁定而受影响。 - Mayank Kumar Chaudhari
@m__ 可以想象这样做是可行的 - 尽管这是一个绕过去缺失驱动功能的过度解决方案,而这个功能可能非常受欢迎。这就是为什么我认为我们可以说服驱动程序供应商。https://source.android.com/setup/contribute/report-bugs - Martin Zeitler

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