Detectar la presión prolongada del botón de encendido

He estado leyendo algunos mensajes aquí en Stackoverflow, y no he encontrado una buena solución, me pregunto si es posible detectar cuando el usuario presione el botón de encendido cuando se trata de apagar el dispositivo, me gustaría Para saber si se puede detectar ese evento, y dejar o no mostrar ese cuadro de diálogo donde aparece (Reiniciar, Apagar, etc …)

He intentado esto:

@Override public boolean dispatchKeyEvent(KeyEvent event) { Toast.makeText(MainActivity.this, event.getKeyCode(), Toast.LENGTH_SHORT).show(); return true; } 

Pero no se muestra, también debe funcionar como un servicio, quiero decir que la aplicación puede o no ser abierto para mostrar ese brindis.

EDITAR

Así es como pongo el onCloseSystemDialog

 //home or recent button public void onCloseSystemDialogs(String reason) { if ("globalactions".equals(reason)) { Toast.makeText(PowerButtonService.this, "yaps", Toast.LENGTH_SHORT).show(); Intent i= new Intent(getBaseContext(), Demo.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplication().startActivity(i); //} else if ("homekey".equals(reason)) { //home key pressed //} else if ("recentapss".equals(reason)) { // recent apps button clicked } } 

Funciona bien, pero sólo cuando el dispositivo está desbloqueado, cuando el dispositivo está bloqueado no está mostrando nada.

También estoy tratando de averiguar cómo eliminar el diálogo cuando el usuario haga clic en powerbutton He intentado esto:

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 

Pero si quiero mostrarlo de nuevo, ¿cómo puedo hacerlo?

Compartir mi método para hacer lo que te gustaría lograr.

Básicamente, lo que hace es

  1. Pedir permiso del sistema para dibujar superposición (Esto no es un permiso normal o vulnerable). Esto no es un permiso de usuario, así que Deberías saber realmente, lo que estás haciendo, preguntándolo.

     public class MainActivity extends AppCompatActivity { public final static int REQUEST_CODE = 10101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkDrawOverlayPermission()) { startService(new Intent(this, PowerButtonService.class)); } } public boolean checkDrawOverlayPermission() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } if (!Settings.canDrawOverlays(this)) { /** if not construct intent to request permission */ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); /** request permission via start activity for result */ startActivityForResult(intent, REQUEST_CODE); return false; } else { return true; } } @Override @TargetApi(Build.VERSION_CODES.M) protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE) { if (Settings.canDrawOverlays(this)) { startService(new Intent(this, PowerButtonService.class)); } } } } 
  2. Inicio de un servicio y agrega una vista especial a WindowManager

  3. Esperando una acción dentro del método onCloseSystemDialogs .

     public class PowerButtonService extends Service { public PowerButtonService() { } @Override public void onCreate() { super.onCreate(); LinearLayout mLinear = new LinearLayout(getApplicationContext()) { //home or recent button public void onCloseSystemDialogs(String reason) { if ("globalactions".equals(reason)) { Log.i("Key", "Long press on power button"); } else if ("homekey".equals(reason)) { //home key pressed } else if ("recentapps".equals(reason)) { // recent apps button clicked } } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_CAMERA || event.getKeyCode() == KeyEvent.KEYCODE_POWER) { Log.i("Key", "keycode " + event.getKeyCode()); } return super.dispatchKeyEvent(event); } }; mLinear.setFocusable(true); View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear); WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); //params WindowManager.LayoutParams params = new WindowManager.LayoutParams( 100, 100, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, PixelFormat.TRANSLUCENT); params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; wm.addView(mView, params); } @Override public IBinder onBind(Intent intent) { return null; } } 

Manifiesto:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="powerbuttonpress"> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:name=".PowerButtonService" android:enabled="true" android:exported="true"> </service> </application> </manifest> 

Service_layout:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout> 

Veo muchas respuestas tratando de hookin al powerbutton. Sin embargo, ¿no sería más fácil escuchar el evento de apagado? No estoy seguro de si esto se ajusta a su necesidad, pero parece que es así.

Simplemente registre un Broadcastreceiver en las siguientes acciones :

 <receiver android:name=".ShutdownReceiver"> <intent-filter> <action android:name="android.intent.action.ACTION_SHUTDOWN" /> <action android:name="android.intent.action.QUICKBOOT_POWEROFF" /> </intent-filter> </receiver> 

No olvide agregar el siguiente permiso:

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

Esta sencilla solución funciona:

  @Override public boolean dispatchKeyEvent(KeyEvent event) { int keyPressed = event.getKeyCode(); if(keyPressed==KeyEvent.KEYCODE_POWER){ Log.d("###","Power button long click"); Toast.makeText(MainActivity.this, "Clicked: "+keyPressed, Toast.LENGTH_SHORT).show(); return true;} else return super.dispatchKeyEvent(event); } 

Si desea detener el sistema emergente , utilice el método onWindowFocusChanged especificado en una de las respuestas siguientes.

La salida mostrará el brindis con "Clicked: 26" como se adjunta a continuación. Introduzca aquí la descripción de la imagen

Para prensas largas …. Por favor, pruebe esto …

 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.KeyEvent; import android.view.WindowManager; import android.widget.Toast; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class demo extends Activity { private final List blockedKeys = new ArrayList(Arrays.asList(KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_POWER)); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); setContentView(R.layout.demo); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(!hasFocus) { // Close every kind of system dialog Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog); Toast.makeText(demo.this, "Your LongPress Power Button", Toast.LENGTH_SHORT).show(); } } @Override public void onBackPressed() { // nothing to do here // … really } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (blockedKeys.contains(event.getKeyCode())) { return true; } else { return super.dispatchKeyEvent(event); } } 

Botón De Prensa Larga De la demostración del poder brindan para la prueba …

Introduzca aquí la descripción de la imagen

Ir con esto

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

Y cuando quiera capturar ese evento haga esto

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_POWER) { // this is method which detect press even of button event.startTracking(); // Needed to track long presses return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_POWER) { // Here we can detect long press of power button return true; } return super.onKeyLongPress(keyCode, event); } 

Se puede hacer con el receptor de radiodifusión. Ver esta respuesta

Prueba esto :

 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { Intent i = new Intent(this, ActivitySetupMenu.class); startActivity(i); return true; } return super.dispatchKeyEvent(event); } 

Puede captar el evento del botón de encendido mediante el método override onKeyDown

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { Log.e("key","long"); /*//disable the system dialog Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog);*/ Toast.makeText(getApplicationContext(),"Power",Toast.LENGTH_SHORT).show(); } return super.onKeyDown(keyCode, event); } 

Como mi conocimiento no podemos hacer esto fuera de la actividad (como el servicio de fondo)

De Skizo-ozᴉʞS pregunta, lo que entiendo, en realidad desea evitar el comportamiento del botón de encendido y que no se puede hacer. Al igual que el botón de inicio presionado algunos eventos en android no se puede evitar a evitar que las personas tienen aplicaciones que no pueden dejar de fumar.

Prueba esto :

  @Override public boolean onKeyLongPress( int keyCode, KeyEvent event ) { if( keyCode == KeyEvent.KEYCODE_POWER ) { //Handle what you want in long press. return true; } return super.onKeyLongPress( keyCode, event ); } 

Añadir esto en Manifiesto:

  <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.PREVENT_POWER_KEY" /> 
  • ¿Cómo enviar MotionEvent sintetizado a través del sistema?
  • Captura de eventos táctiles en un elemento de lista de Android e impide el desplazamiento
  • Insertar varios eventos en el calendario de Android
  • ¿Cuánto dura el evento onLongPress en Android?
  • Cómo enviar eventos táctiles (Eventos de pantalla) a otra aplicación en android
  • ¿Cuándo debo guardar datos en SQLite ingresados ​​en un fragmento en mi aplicación de Android?
  • Java events, handlers and listeners pregunta
  • ¿Cómo puede detectar la vista que está pasando cuando realiza un evento táctil?
  • Inyectar eventos en Android sin root
  • Evento de supervivencia de botón de Android
  • Averigüe si el receptor de eventos hijo en firebase carga completamente todos los datos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.