Varios dispositivos Android, como la serie Nexus, tienen un sensor magnético que NO es el android.hardware.Sensor.TYPE_MAGNETIC_FIELD que se usa exclusivamente para encender/apagar la pantalla automáticamente usando fundas de teléfono que tienen un pequeño imán en su interior.
En mi aplicación, estoy usando la detección de imanes usando android.hardware.Sensor.TYPE_MAGNETIC_FIELD y SensorManager para detectar que el usuario toca el teléfono en un estuche con algunos imanes adentro.
El código funciona sin problemas, el problema es que es extremadamente fácil en esos dispositivos activar accidentalmente el sensor de encendido/apagado de la pantalla, apagando la pantalla.
He intentado:
android:keepScreenOn="true" en el XMLandroid.permission.WAKE_LOCK y adquiriendo un wake-lock a través de PowerManager .Ambos sin éxito.
¿Hay alguna forma de desactivar temporalmente este sensor mientras se reanuda mi actividad?
KeepScreenOn = true en el manifiesto tampoco funciona aquí, ya que la acción del sensor de efecto Hall es la misma que presionar el botón de encendido.
Aquí, ofrezco una solución alternativa que he probado. En este enfoque, muestra su actividad independientemente de que el sensor de efecto Hall bloquee el dispositivo y apague la pantalla.
Antes de comenzar la acción de desbloqueo
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);créditos por el código anterior: https://stackoverflow.com/a/45951927/9640177
También asegúrese de agregar Permisos
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.WAKE_LOCK" />Establecer estas banderas asegurará que su ventana sea visible sobre la pantalla de bloqueo.
Ahora, escuche la intención ACTION_SCREEN_OFF. Para hacer esto, agregue un receptor de transmisión que escuche esta intención transmitida por el sistema. Debe registrar el receptor localmente. (stackoverflow.com/a/9478013/9640177) en el manifiesto
<receiver android:name=".receiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_OFF"/> </intent-filter> </receiver>Clase de receptor
public class receiver extends BroadcastReceiver { MyActivity activity; receiver(MyActivity activity){ this.activity = activity; } @Override public void onReceive(final Context context, Intent intent) { activity.turnOnScreen(); } }actividad interior
// 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(); }crédito - https://stackoverflow.com/a/44706632/9640177 Esto encenderá la pantalla.
No olvide quitar estas banderas después de que su actividad haya hecho el trabajo y no requiera estar al frente.
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);Esto hará que su ventana desaparezca de la pantalla de bloqueo y que la aplicación funcione normalmente.
Espero que esto ayude.
la solución más pragmática al problema podría ser...
para deshabilitar la función de cubierta inteligente físicamente en lugar de por software.
p.ej. tome una hoja de afeitar y unas pinzas y luego retire el imán.
... o simplemente consigue otra funda sin imán.
alternativamente, presente un error contra drivers/input/lid.c .