para - Cómo conectar el botón de encendido en Android?
descargar aplicacion para encender y apagar el celular android (7)
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);
}
}
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?
Compartiendo un método para escuchar el botón de Encendido y pulsación larga. Funciona con permisos API 23+:
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)); } } } }
Iniciar un servicio y agrega una vista especial a
WindowManager
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:
<?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>
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.
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:
<uses-permission android:name="android.permission.PREVENT_POWER_KEY" />
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 programa si lo desea.
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.
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);
}
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;
}};