简体   繁体   中英

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.

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.

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
  • using the permission android.permission.WAKE_LOCK and acquiring a wake-lock via 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.

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

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. 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

    <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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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