2010-09-13 16 views

Respuesta

7

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

que no trabaja para mí :( –

+5

favor comparten código completo –

+2

esto funciona ONL y cuando es una pulsación larga – Sjk

1

Usted puede sobrescribir los public boolean onKeyDown(int keyCode, KeyEvent event) y public boolean onKeyUp(int keyCode, KeyEvent event) funciones en el tipo de actividad y prueba si keyCode es igual a KeyEvent.KEYCODE_POWER.

No he probado esto, pero supongo que el sistema trata esto como lo hace con la clave Home, ya que no puede detener el sistema para que reciba el evento clave, solo puede observar que ocurre. Para probar esto, intente devolver True de las funciones anteriores y vea si esto capta el evento clave.

4

en que la actividad Añadir:

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 especial ... no estoy seguro si se puede dar problemas a usted.

0

usted tiene que utilizar 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; 

}}; 
+2

¿Funciona? Estoy bastante seguro de que la pantalla seguirá sonando. – Pandalover

37

Las respuestas existentes no responden a la pregunta por completo y dejar de lado los detalles suficientes que no van a trabajar sin más investigación . Compartiré lo que he aprendido para resolver esto.

En primer lugar es necesario agregar el siguiente permiso a su archivo de manifiesto:

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

Para manejar presiones cortas y largas añaden los siguientes reemplazos 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: Es Vale la pena señalar que onKeyDown() se activará varias veces antes de que onKeyLongPress lo haga, por lo que es posible que desee desencadenar 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 empezar a interceptar la tecla de encendido es necesario establecer la siguiente bandera de su actividad:

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

Para detener la interceptación de la tecla de encendido (que permite la funcionalidad estándar):

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

Puede alterna entre los dos modos repetidamente en tu programa si lo deseas.

+4

¿funciona esto con todas las versiones de API? Intento las API 8 y 15 y no hay ningún parámetro PREVENT_POWER_KEY en LayoutParams. ¿Podrías tal vez aquí el valor de este param? – Koger

+1

El valor de WindowManager.LayoutParams.PREVENT_POWER_KEY es 0x80000000 Pero lo que parece es que este es un valor oculto o específico solo para Cyanogenmod (lo cual sería inquietante si es cierto). El proyecto para el que hice esto fue API 10, pero modifiqué el SDK para exponer las API ocultas y lo ejecuté en Cyanogenmod 7. –

+3

onKeyDown solo funciona cuando se produce un evento de pulsación larga, en realidad OnKeyLongPress nunca se dispara con el botón de encendido, en menos en un Motorola Droid X2. – JPM

3

Como se ha mencionado 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); 
    } 
} 
2

compartir un método para escuchar botón de encendido pulsado.Funciona con permisos API 23+:

  1. pedir permiso al sistema de draw overlay (Esto no es un permiso normal o vulnerables). 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. Inicio de un servicio y agrega una vista especial para WindowManager

  3. Esperando una acción dentro onCloseSystemDialogs método View 's.

    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> 
+1

¡Brillante! Gracias. Un problema aquí es que el teclado suave no se puede abrir :( – Zohar

+0

@R.Zagórski Hola, pero esto no imprime nada – Abhishek

+0

Si alguien está teniendo problemas con el teclado no se muestra, puede agregar 'WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE' a los parámetros de su gestor de ventanas para repararlo –

Cuestiones relacionadas