Pregunta Detecta el botón de inicio presiona en Android


Esto me ha estado volviendo loco durante un tiempo.

¿Hay alguna forma de detectar de manera confiable si se presionó el botón de inicio en una aplicación de Android?

En su defecto, ¿hay alguna forma sólida de decir qué causó que una actividad entrara en Pausa? Es decir, ¿podemos detectar si fue causado por un nuevo lanzamiento de actividad o presionando back / home.

Una sugerencia que he visto es anular onPause () y llamar a isFinishing () pero esto devolverá falso al presionar el botón de inicio como lo haría si se inicia una nueva actividad, por lo que no se puede distinguir entre los dos.

Cualquier ayuda muy apreciada.

** Actualización **: Gracias a @ android-hungry por este enlace: http://nisha113a5.blogspot.com/

Sobrevalorando el siguiente método:

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);           
}

Luego, el siguiente evento será despedido para presionar botones de inicio:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

    if(keyCode == KeyEvent.KEYCODE_HOME)
    {
       //The Code Want to Perform. 
    }
});

No estoy seguro de si hay algún efecto secundario con esta línea:

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);   

Por lo tanto, parece que, contrario a la creencia popular, de hecho puedes escuchar la clave de inicio. Preocupantemente, puede devolver falso y tener la tecla de inicio no hacer nada.

Actualizar: Como se esperaba, hay algunos efectos secundarios con esto: parece que los videos incrustados y los mapas de Google no son visibles con este modo habilitado.

Actualizar: Supuestamente, este truco ya no funciona a partir de Android 4.0 en adelante


75
2018-01-16 15:12


origen


Respuestas:


El siguiente código funciona para mí :)

HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
    @Override
    public void onHomePressed() {
        // do something here...
    }
    @Override
    public void onHomeLongPressed() {
    }
});
mHomeWatcher.startWatch();
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

public class HomeWatcher {

    static final String TAG = "hg";
    private Context mContext;
    private IntentFilter mFilter;
    private OnHomePressedListener mListener;
    private InnerReceiver mReceiver;

    public HomeWatcher(Context context) {
        mContext = context;
        mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
    }

    public void setOnHomePressedListener(OnHomePressedListener listener) {
        mListener = listener;
        mReceiver = new InnerReceiver();
    }

    public void startWatch() {
        if (mRecevier != null) {
            mContext.registerReceiver(mReceiver, mFilter);
        }
    }

    public void stopWatch() {
        if (mRecevier != null) {
            mContext.unregisterReceiver(mReceiver);
        }
    }

    class InnerReceiver extends BroadcastReceiver {
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
        final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    Log.e(TAG, "action:" + action + ",reason:" + reason);
                    if (mListener != null) {
                        if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                            mListener.onHomePressed();
                        } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                            mListener.onHomeLongPressed();
                        }
                    }
                }
            }
        }
    }
}
public interface OnHomePressedListener {
    public void onHomePressed();

    public void onHomeLongPressed();
}

99
2018-01-15 03:16



Esta es una vieja pregunta, pero podría ayudar a alguien.

@Override
protected void onUserLeaveHint()
{
    Log.d("onUserLeaveHint","Home button pressed");
    super.onUserLeaveHint();
}

De acuerdo con la documentación, se llama al método onUserLeaveHint () cuando el usuario hace clic en el botón de inicio O cuando algo interrumpe su aplicación (como una llamada de teléfono entrante).

Esto funciona para mí ... :)


41
2017-07-07 14:28



Es imposible detectar y / o interceptar el botón INICIO desde dentro de una aplicación de Android. Esto está integrado en el sistema para evitar aplicaciones maliciosas que no pueden salir.


10
2018-01-16 15:20



Necesitaba iniciar / detener la música de fondo en mi aplicación cuando se abre y cierra la primera actividad, o cuando cualquier actividad se pausa con el botón de inicio y luego se reanuda desde el administrador de tareas. Reproducción pura parada / reanudación en Activity.onPause() y Activity.onResume() interrumpí la música por un tiempo, así que tuve que escribir el siguiente código:

@Override
public void onResume() {
  super.onResume();

  // start playback here (if not playing already)
}

@Override
public void onPause() {
  super.onPause();

  ActivityManager manager = (ActivityManager) this.getSystemService(Activity.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(Integer.MAX_VALUE);
  boolean is_finishing = this.isFinishing();
  boolean is_last = false;
  boolean is_topmost = false;
  for (ActivityManager.RunningTaskInfo task : tasks) {
    if (task.topActivity.getPackageName().startsWith("cz.matelier.skolasmyku")) {
      is_last = task.numRunning == 1;
      is_topmost = task.topActivity.equals(this.getComponentName());
      break;
    }
  }

  if ((is_finishing && is_last) || (!is_finishing && is_topmost && !mIsStarting)) {
    mIsStarting = false;
    // stop playback here
  }
}

que interrumpe la reproducción solo cuando la aplicación (todas sus actividades) está cerrada o cuando se presiona el botón de inicio. Desafortunadamente no logré cambiar el orden de las llamadas de onPause() método de la actividad inicial y onResume() de la actividad iniciada cuando Activity.startActivity() se llama (o detecta en onPause() esa actividad está lanzando otra actividad de otra manera) por lo que este caso debe manejarse especialmente:

private boolean mIsStarting;

@Override
public void startActivity(Intent intent) {
  mIsStarting = true;
  super.startActivity(intent);
}

Otro inconveniente es que esto requiere GET_TASKS permiso agregado a AndroidManifest.xml:

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

La modificación de este código que solo reacciona al presionar el botón de inicio es directo.


7
2018-03-14 19:57



Anular onUserLeaveHint() en la actividad. Nunca se volverá a llamar a la actividad cuando aparezca una nueva actividad o el usuario presione nuevamente.


4
2018-04-21 11:41



Intenta crear un contador para cada pantalla. Si el usuario toca INICIO, entonces el contador será cero.

public void onStart() {
  super.onStart();
  counter++;
}

public void onStop() {
  super.onStop();
  counter--;    
  if (counter == 0) {
      // Do..
  }
}

2
2017-08-14 18:04



Podría considerar una solución de Andreas Shrade en su publicación de Cómo crear un modo de quiosco de trabajo en Android. Es un poco hacky, pero teniendo en cuenta las razones por las que se impide la interceptación del botón de inicio, tiene que ser;)


2
2017-07-28 14:15



Tuve este problema, y ​​dado que anular el método onKeyDown () no logró nada debido a que el sistema android subyacente no llamó a este método, lo resolví con la anulación de onBackPressed (), y tuve un valor booleano establecido en false , porque presioné hacia atrás, déjame mostrarte lo que quiero decir en código:

import android.util.Log;
public class HomeButtonActivity extends Activity {
    boolean homePressed = false;
    // override onCreate() here.

    @Override
    public void onBackPressed() {
        homePressed = false; // simply set homePressed to false
    }

    @Overide
    public void onResume() {
        super.onResume();
        homePressed = true; // default: other wise onBackPressed will set it to false
    }

    @Override
    public void onPause() {
        super.onPause();
        if(homePressed) { Log.i("homePressed", "yay"); }
    }

Entonces, la razón por la que esto funcionó es porque la única forma de navegar fuera de esta actividad es presionar hacia atrás o hacia la casa, así que si se presionó, entonces sé que la causa no estaba en casa, pero la causa fue el hogar, por lo tanto configuré el booleano predeterminado valor para el hogarPresionado para ser cierto. Sin embargo, esto solo funcionará con una sola instancia de actividad en su aplicación, ya que de lo contrario tendrá más posibilidades de hacer que se invoque el método onPause ().


2
2017-07-30 22:49



onUserLeaveHint ();

anula este método de clase de actividad. Esto detectará el clic de la tecla de inicio. Este método se llama justo antes de la activación de OnPause () de la actividad. Pero no se ejecutará cuando se interrumpa una actividad, como una actividad en llamada entra en primer plano, aparte de esas interrupciones llamará cuando el usuario haga clic en la tecla de inicio.

@Override
protected void onUserLeaveHint() {
    super.onUserLeaveHint();
    Log.d(TAG, "home key clicked");
}

1
2017-10-06 14:18



Una opción para su aplicación sería escribir una Pantalla de inicio de reemplazo utilizando android.intent.category.HOME Intent. Creo que este tipo de intención puede ver el botón de inicio.

Más detalles:

http://developer.android.com/guide/topics/intents/intents-filters.html#imatch


0
2018-01-16 15:48



La aplicación promedio puede llevarse bien sin necesidad de saber la diferencia entre una prensa hogareña y un evento de pausa. En otras palabras, onPause () suele ser suficiente.

¿Por qué quieres hacer esto? Dándonos más información sobre sus intenciones podría conducir a una mejor estrategia general para usted.


0
2018-01-16 15:54