Cómo conectar el botón de encendido en Android?

En un dispositivo Android, donde los únicos botones son los botones de volumen y un botón de encendido, quiero que la aplicación reaccione a las pulsaciones del botón de encendido (largo y corto). ¿Cómo se hace esto?

Las respuestas existentes no responden completamente a la pregunta y omiten los detalles suficientes que no funcionarán sin más investigación. Compartiré lo que he aprendido para resolver esto.

Primero necesita agregar el siguiente permiso a su archivo de manifiesto:

 

Para manejar prensas cortas y largas, agregue las siguientes anulaciones a su clase de actividad:

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_POWER) { // Do something here... 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) { // Do something here... return true; } return super.onKeyLongPress(keyCode, event); } 

Nota: Vale la pena señalar que onKeyDown () se activará varias veces antes de que onKeyLongPress lo haga, por lo que puede desear disparar onKeyUp () u otra lógica para evitar actuar sobre una serie de llamadas onKeyDown () cuando el usuario realmente está presionando .

Creo que la siguiente parte es solo para Cyanogenmod. Si la constante PREVENT_POWER_KEY no está definida, entonces no debería necesitarla.

Para comenzar a interceptar la clave de encendido, debe establecer la siguiente marca de su actividad:

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

Para detener la interceptación de la clave de encendido (permitiendo la funcionalidad estándar):

 getWindow().clearFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY); 

Puede cambiar entre los dos modos repetidamente en su progtwig si lo desea.

Solución:

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

En tu actividad agrega:

 public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { // do what you want with the power button return true; } return super.onKeyDown(keyCode, event); } 

Aunque … este tipo de llaves son de alguna manera especiales … no estoy seguro de si te puede dar problemas.

Como se menciona aquí https://stackoverflow.com/a/15828592/1065357

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(!hasFocus) { Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog); } } 

Compartiendo un método para escuchar el botón de Encendido y pulsación larga. Funciona con permisos API 23+:

  1. Pedir permiso del sistema para dibujar superposición (este no es un permiso normal o vulnerable). Esto no es un permiso del usuario, por lo que debe saber realmente lo que está haciendo, solicitá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. Iniciar 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 ("recentapss".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:

               

service_layout:

    

Puede sobrescribir las public boolean onKeyDown(int keyCode, KeyEvent event) y public boolean onKeyUp(int keyCode, KeyEvent event) en su clase Activity y probar si keyCode es igual a KeyEvent.KEYCODE_POWER .

No probé esto, pero supongo que el sistema trata esto como lo hace con la tecla de Home que no puede evitar que el sistema reciba el evento clave, solo puede observar que ocurre. Para probar esto, intente devolver True desde las funciones anteriores y vea si esto capta el evento clave.

tienes que usar esto:

 BroadcastReceiver screenoff = new BroadcastReceiver() { public static final String Screenoff = "android.intent.action.SCREEN_OFF"; @Override public void onReceive(Context context, Intent intent) { if (!intent.getAction().equals(Screenoff)) return; //put code to handle power press here return; }};