¿Cómo puedo detectar al usuario presionando la tecla INICIO en mi actividad?

¿Puede decirme por favor cómo puede mi actividad detectar al usuario presionando la tecla INICIO ?

Gracias.

Actualización [agosto de 2015]: según el comentario de JM Lord , esta respuesta podría no funcionar como se desea para dispositivos Lollipop y superiores. Ver alternativa a getRunningTasks en Android L


Aunque, es una pregunta antigua, pero la mayoría de las respuestas no me funcionaron en el nivel 17 de API y superior. Estoy respondiendo lo que finalmente funcionó para mí. He intentado con muchos métodos, pero ninguno de ellos funciona como hoy. Intenté las respuestas en

Método de llamada cuando se presiona el botón de inicio en Android

Detecta el botón de inicio presiona en Android y

Anulando el botón Inicio, ¿cómo me deshago de la elección? . Lo esencial era que Home es como un botón de escape de emergencia. Entonces no puedes anularlo pero puedes detectarlo de alguna manera.

Algunos de los que probé (incluidas las respuestas anteriores) y que no funcionaron son:

  1. Usando keyCode==KeyEvent.KEYCODE_HOME de muchas maneras como se indicó anteriormente. Ahora, si lee la documentación de KeyEvent.KEYCODE_HOME , dice que This key is handled by the framework and is never delivered to applications . Entonces no es más válido ahora.

  2. Intenté usar onUserLeaveHint() . La documentación dice:

    Se llama como parte del ciclo de vida de la actividad cuando una actividad está a punto de pasar a segundo plano como resultado de la elección del usuario. Por ejemplo, cuando el usuario presiona la tecla Inicio, se llamará a onUserLeaveHint (), pero cuando una llamada entrante hace que la Actividad de guardia se ponga automáticamente en primer plano.

    El problema es que también se llama al método cuando onUserleaveLint() una Activity desde la actividad a la que llamas onUserleaveLint() , como era mi caso. Consulte la pregunta de Android onBackPressed / onUserLeaveHint para obtener más información. Por lo tanto, no estoy seguro de que se llame SOLO al presionar el botón de inicio.

  3. Llamar a onStop() . También se puede invocar cuando una actividad se agrega a la actividad existente y la cubre por completo. Entonces esto tampoco funcionará.

Finalmente, lo siguiente funcionó para mí:

¿Cómo ver las aplicaciones actuales en ejecución en Android? Puedes decir que si la tuya es la tarea reciente que se muestra al presionar el botón de inicio, entonces se envió a fondo.

Entonces, en su onPause() de la actividad en la que está tratando de detectar el botón de inicio presionado, puede verificar si la aplicación se ha enviado a segundo plano.

 @Override public void onPause() { if (isApplicationSentToBackground(this)){ // Do what you want to do on detecting Home Key being Pressed } super.onPause(); } 

Función para verificar si la tuya es la aplicación que se envió más recientemente al fondo:

 public boolean isApplicationSentToBackground(final Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { return true; } } return false; } 

Gracias a @idish por señalar que no olvide incluir el siguiente permiso en su manifiesto:

  

No estoy seguro de si hay algún inconveniente de esto, pero funcionó bien para mí. Espero que ayude a alguien algún día.

PD: si usa este método en una actividad que se ha lanzado con el indicador FLAG_ACTIVITY_NO_HISTORY , esto no será útil, ya que verifica el historial reciente para averiguar si se hizo clic en el botón Home .

Puede detectar presionar un botón HOME a través de Activity.onUserLeaveHint (). Este método se llama en dos situaciones; cuando el usuario presiona INICIO y cuando se inicia una nueva actividad. Asegúrese de diferenciar de alguna manera entre los dos.

No hay forma formal de ser notificado de una pulsación de tecla “INICIO”. Pero hay un trabajo bastante simple para que su aplicación distinga entre presionar una tecla “INICIO” y cualquier otra acción que pueda hacer que la Actividad se detenga.

Para cada clase que necesite realizar alguna acción con la tecla “INICIO”, haga que se extiendan desde una actividad que contenga esto:

 /**************************************** On Home **********************************/ private boolean leaveCalled = false; @Override public void startActivity(Intent intent) { leaveCalled= true; super.startActivity(intent); } @Override public void onBackPressed() { leaveCalled = true; super.onBackPressed(); } @Override protected void onStop() { super.onStop(); // Home button pressed if(!leaveCalled) { // Do whatever you like. } leaveCalled = false; } 

EDITAR

También necesitarás extender tus Fragmentos de una clase padre que contenga esto. Esto se debe a que, de lo contrario, los fragmentos proporcionarían una ruta adicional para alternar entre las actividades de la aplicación de forma esperada y no como “INICIO”.

 @Override public void startActivity(Intent intent) { getActivity().startActivity(intent); } 

EDIT 2

Me estoy acercando a pensar que esta no es la forma más fácil de lidiar con esto … También debe agregarConfigurationChange = “orientación” a todas sus actividades que utilizan este método. Entonces puedes agregar esto:

 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); leaveCalled = true; finish(); startActivity(getIntent()); } 

EDIT 3

Urgh

 @Override public void finish() { leaveCalled = true; super.finish(); } 

No puede capturar el evento HOME e interceptarlo de ninguna manera. El usuario siempre será llevado a la pantalla de inicio de su dispositivo cuando presione la tecla de inicio.

Si necesita saber cuándo se enviará su actividad a un segundo plano, como si el usuario presionara las teclas de inicio o de retroceso, implementaría el método onStop ().

utiliza el método UserLeaveHint () en tu actividad

 @Override protected void onUserLeaveHint() { super.onUserLeaveHint(); } 

http://developer.android.com/reference/android/app/Activity.html#onUserLeaveHint ()

Se puede hacer (hasta 2,3 atleast). Probado en la versión de Android 2.3.5 HTC Wildfire-S no rooteado. Fragmento de código para capturar / deshabilitar todas las teclas de control:

 @Override public void onAttachedToWindow() { super.onAttachedToWindow(); this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); } public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH ) { Toast.makeText(getApplicationContext(),"You pressed a control button with keyCode : " + keyCode, Toast.LENGTH_SHORT).show(); return false; } else { Toast.makeText(getApplicationContext(),"You pressed" + keyCode, Toast.LENGTH_SHORT).show(); } return true; } public boolean onKeyUp(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH ) { return false; } else { // Do nothing } return true; } 

Puede escribir un oyente de difusión y configurar el filtro para

  

Desde el receptor de emisión, inicia tu actividad / notifica a la actividad.

Encontré esta solución basada en la sugerencia de @Springfeed. Como la pregunta es bastante genérica, tenga en cuenta que esta solución particular:

  • Trabajar en Lollipop, así como versiones inferiores de Android (mi código anterior basado en ActivityManager falló en Lollipop)
  • Captura los botones Inicio e Historial
  • No capturará Inicio si la actividad en sí misma se define como Inicio – Siempre
  • Capturará a casa si la actividad es una de muchas opciones de inicio o no es el hogar en absoluto.

Este código está en mi clase de Activity base (de la cual todas las actividades heredan)

  public boolean startingActivity = false; @Override protected void onUserLeaveHint() { if(startingActivity) { // Reset boolean for next time startingActivity = false; } else { // User is exiting to another application, do what you want here Log.i(TAG, "Exiting"); ... } } @Override public void startActivity(Intent intent) { startingActivity = true; super.startActivity(intent); } @Override public void startActivityForResult(Intent intent, int requestCode) { startingActivity = true; super.startActivityForResult(intent, requestCode); } 

Como algunos métodos también pueden usar el contexto de la aplicación para ejecutar intents, definí ContextWrapper en mi clase Application para cambiar también el booleano (tenga en cuenta que tengo acceso estático a la actividad más alta de mi propia aplicación a través de esa clase base).

 public class MyContext extends ContextWrapper { public MyContext(Context base) { super(base); } @Override public void startActivity(Intent intent) { BaseActivity activity = BaseActivity.getActivity(); if(activity != null) { activity.startingActivity = true; } super.startActivity(intent); } } 

Uno podría querer anular startActivities (…) también, si es necesario.

Espero que esto ayude 🙂

 android.text.method.KeyListener.onKeyDown([view],[text],KEYCODE_HOME,[event]) 

No estoy seguro de cómo encajan los otros parámetros, o incluso cómo implementar lo anterior, pero la información está en la documentación de keylistner.

Pero también mencionan en otra página que la llave de casa SIEMPRE se va a casa, no se puede cambiar eso. Entonces, si planeas tener algún tipo de diálogo “¿estás seguro de que quieres salir?”, Eso no funcionaría.

 public boolean isApplicationSentToBackground(final Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { return true; } } return false; } public void onPause() { super.onPause(); if(isApplicationSentToBackground(this)) { Log.i("Home", "Home Pressed..!"); } } 
 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME) { //The Code Want to Perform. } });