android events

android - Detectar el botón de encendido presionar prolongadamente



events (11)

Para pulsación larga ... Por favor, intente esto ...

@Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.i(TAG,"Accessibilityevent"); if (event == null || event.getPackageName()==null||event.getClassName()==null) return; if (event.getClassName().toString().contains("globalactions")){ //TRIGGER YOUR CODE HERE } ....

Mantenga presionado el botón de la función de tostadas para probar ...

He estado leyendo algunas publicaciones aquí en Stackoverflow, y no encontré una buena solución, me pregunto si es posible detectar cuándo el usuario presiona el botón de encendido al intentar apagar el dispositivo, me gustaría para saber si puede detectar ese evento y mostrar o no 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 aparece, también debería funcionar como un servicio, quiero decir que la aplicación se puede abrir o no 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 solo cuando el dispositivo está desbloqueado, cuando el dispositivo está bloqueado no muestra nada.

También estoy tratando de descubrir cómo eliminar el diálogo cuando el usuario hace clic en el botón de encendido Intenté esto:

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

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


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

Básicamente, lo que hace es

  1. Solicitar permiso del sistema para dibujar superposición (este no es un permiso normal o vulnerable). Esto no es un permiso de usuario, por lo que realmente debe saber qué está haciendo al solicitarlo.

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


De la pregunta de Skizo-ozᴉʞS, lo que entiendo, en realidad quieres evitar el comportamiento del botón de encendido y eso no se puede hacer. Al igual que el botón de inicio presionado, algunos eventos en Android no se pueden evitar para evitar que las personas tengan aplicaciones que no pueden abandonar.


El método utilizado anteriormente por R. Zagórski me funcionó muy bien durante mucho tiempo, pero a partir de alguna revisión de Android 9, el método onCloseSystemDialogs dejó de recibir "globalacciones".

Como solución alternativa, mi aplicación ya está usando Accesibilidad. Desde el interior del AccessibilityService puede agregar este código en onAccessibilityEvent

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

Tenga en cuenta que si puse el comentario "ACTIVAR SU CÓDIGO AQUÍ", en realidad solo llamo al mismo código que estaba anteriormente en onCloseSystemDialogs .

Tenga en cuenta que hasta ahora solo se ha probado que funciona en un Pixel 2 con el último Android. No tengo ningún otro teléfono con una versión lo suficientemente reciente, así que no puedo probar si la solución es suficientemente genérica en todos los teléfonos.


Esta solución simple 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 la onWindowFocusChanged emergente del sistema , use el método onWindowFocusChanged especificado en una de las respuestas a continuación.

La salida mostrará la tostada con "Clicked: 26" como se adjunta a continuación.


Ir con esto

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

Y cuando quieras capturar ese evento, haz 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 difusión. ver esta respuesta


La respuesta aceptada funciona perfectamente hasta Android Oreo pero no en Android P. Para que funcione en Android P, deberá usar el Servicio de accesibilidad

Clase de servicio

import android.accessibilityservice.AccessibilityService; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import com.bm.yucasa.Utils.LocationSetup; import static com.bm.yucasa.controller.AppController.TAG; public class PowerServiceTwo extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { Log.i(TAG,"Accessibilityevent"); if (event == null || event.getPackageName()==null||event.getClassName()==null) return; if (event.getClassName().toString().contains("globalactions")){ LocationSetup locationSetup = LocationSetup.getInstance(PowerServiceTwo.this); if (locationSetup.isConnected) { locationSetup.startOnDemandLocationUpdates(false, "0"); } else { //Toast.makeText(getApplicationContext(), "please check gps", Toast.LENGTH_SHORT).show(); } } } @Override public void onInterrupt() { } }

Como no puede utilizar el método startService () para iniciar un Servicio de accesibilidad,

Así que aquí está cómo puedes habilitarlo.

Intent openSettings = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); openSettings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(openSettings);


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


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

Agregue esto en Manifiesto:

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


Veo muchas respuestas tratando de conectar el botón de encendido. Sin embargo, ¿no sería más fácil escuchar el evento de apagado? No estoy seguro de si esto se ajusta a sus necesidades, pero parece que sí.

Simplemente registre un receptor de difusión para las siguientes action(s) :

<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 olvides agregar el siguiente permiso:

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


Puede capturar el evento del botón de encendido anulando el método 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 sé, no podemos hacer esta actividad externa (como el servicio en segundo plano)