Détecter la pression sur le bouton d’accueil dans Android

Cela me rend fou depuis un moment maintenant.

Est-il possible de détecter de manière fiable si le bouton d’accueil a été enfoncé dans une application Android?

À défaut, existe-t-il un moyen solide de dire ce qui a causé une activité à onPause? c.-à-d. peut-on détecter si elle a été causée par le lancement d’une nouvelle activité ou en appuyant sur back / home.

Une suggestion que j’ai vue est de remplacer onPause () et d’appeler isFinishing (), mais cela retournera false si vous appuyez sur le bouton d’accueil comme si une nouvelle activité commençait.

Toute aide très appréciée.

** Mise à jour **: Merci à @ android-faim pour ce lien: http://nisha113a5.blogspot.com/

Surmonter la méthode suivante:

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

L’événement suivant sera alors déclenché pour les pressions sur le bouton d’accueil:

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME) { //The Code Want to Perform. } }); 

Je ne suis pas sûr qu’il y ait des effets secondaires avec cette ligne:

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

Il semblerait donc que, contrairement à la croyance populaire, vous pouvez en fait écouter la clé de la maison. De manière inquiétante, vous pouvez renvoyer la fausse et faire en sorte que la clé d’accueil ne fasse rien.

Mise à jour : Comme prévu, il y a quelques effets secondaires avec cela – il semble que les vidéos intégrées et Google Maps ne sont pas visibles avec ce mode activé.

Mise à jour : Ce hack n’aurait plus fonctionné à partir d’Android 4.0

Le code suivant fonctionne pour moi 🙂

 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 Ssortingng 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 Ssortingng SYSTEM_DIALOG_REASON_KEY = "reason"; final Ssortingng SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; final Ssortingng SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; final Ssortingng SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; @Override public void onReceive(Context context, Intent intent) { Ssortingng action = intent.getAction(); if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { Ssortingng reason = intent.getSsortingngExtra(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(); } 

C’est une vieille question mais cela pourrait aider quelqu’un.

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

Selon la documentation, la méthode onUserLeaveHint () est appelée lorsque l’utilisateur clique sur le bouton d’accueil OU lorsque quelque chose interrompt votre application (comme un appel téléphonique entrant).

Cela fonctionne pour moi .. 🙂

Il est impossible de détecter et / ou d’intercepter le bouton HOME depuis une application Android. Ceci est intégré au système pour empêcher les applications malveillantes qui ne peuvent pas être abandonnées.

Je devais démarrer / arrêter la musique de fond dans mon application à l’ouverture et à la fermeture de la première activité ou lorsqu’une activité est interrompue par le bouton principal, puis reprise du gestionnaire de tâches. La lecture pure s’arrêtant / reprenant dans Activity.onPause() et Activity.onResume() interrompu la musique pendant un moment, j’ai donc dû écrire le code suivant:

 @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 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 } } 

qui interrompt la lecture uniquement lorsque l’application (toutes ses activités) est fermée ou lorsque le bouton d’accueil est enfoncé. Malheureusement, je n’ai pas réussi à modifier l’ordre des appels de la méthode onPause() de l’activité de démarrage et à onResume() de l’activité lancée lorsque Activity.startActivity() est appelée (ou détecte dans onPause() que cette activité lance une autre activité) façon), donc ce cas doit être traité spécialement:

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

Un autre inconvénient est que cela nécessite GET_TASKS autorisation GET_TASKS ajoutée à AndroidManifest.xml :

  

La modification de ce code, qui ne réagit que sur l’appui sur le bouton d’accueil, est simple.

Remplacez onUserLeaveHint() dans l’activité. Il n’y aura jamais de rappel à l’activité lorsqu’une nouvelle activité survient ou que l’utilisateur appuie sur la touche de retour.

Essayez de créer un compteur pour chaque écran. Si l’utilisateur touche HOME, le compteur sera à zéro.

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

Vous pourriez envisager une solution par Andreas Shrade dans son post sur Comment créer un mode Kiosque de travail dans Android . C’est un peu piraté, mais compte tenu des raisons qui empêchent l’interception du bouton d’accueil, il faut que:

J’ai eu ce problème, et depuis que la méthode onKeyDown () n’a rien accompli à cause du système Android sous-jacent qui n’a pas appelé cette méthode, j’ai résolu ce problème en remplaçant onBackPressed (), et j’ai mis une valeur booléenne à false , parce que j’ai reculé, laissez-moi vous montrer ce que je veux dire dans le code:

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

Donc, la raison pour laquelle cela a fonctionné est que la seule façon de naviguer en dehors de cette activité est de revenir en arrière ou à la maison, donc si la presse était pressée, je sais que la cause n’était pas à la maison. valeur pour homePressed pour être vrai. Cependant, cela ne fonctionnera qu’avec une seule instance d’activité dans votre application, car sinon vous avez plus de possibilités de provoquer l’appel de la méthode onPause ().

onUserLeaveHint ();

remplacer cette méthode de classe d’activité.Cela détectera le clic de la touche Accueil. Cette méthode est appelée juste avant le rappel onPause () de l’activité. Mais elle ne sera pas appelée lorsqu’une activité est interrompue comme une activité en cours arrive en avant-plan.

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

Une option pour votre application serait d’écrire un écran d’accueil de remplacement en utilisant l’intention android.intent.category.HOME. Je crois que ce type d’intention, vous pouvez voir le bouton d’accueil.

Plus de détails:

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

Puisque vous souhaitez uniquement que l’activité racine soit redessinée au lancement de l’application, vous pouvez peut-être obtenir ce comportement en modifiant les modes de lancement, etc. dans le manifeste?

Par exemple, avez-vous essayé d’appliquer l’ atsortingbut android: clearTaskOnLaunch = “true” à votre activité de lancement, peut-être en tandem avec Android: launchMode = “singleInstance” ?

Tasks and Back Stack est une excellente ressource pour affiner ce type de comportement.

C’est une mauvaise idée de changer le comportement de la clé principale. C’est pourquoi Google ne vous autorise pas à remplacer la clé principale. Je ne plaisante pas avec la clé de la maison en général. Vous devez donner à l’utilisateur un moyen de sortir de votre application si elle est envoyée dans les mauvaises herbes pour une raison quelconque.

J’imagine que tout travail autour aura des effets secondaires indésirables.

La méthode override onUserLeaveHint peut intercepter l’événement de presse à la maison, mais vous devez également tenir compte des événements de clic de l’utilisateur. les codes suivants fonctionnent pour moi.

 private boolean isUserClickToLeave = false; private Handler mHandler = new Handler(); Runnable resetUserClickFlagRunnable = new Runnable() { @Override public void run() { isUserClickToLeave = false; } }; @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP) { isUserClickToLeave = true; mHandler.removeCallbacks(resetUserClickFlagRunnable); mHandler.postDelayed(resetUserClickFlagRunnable, 1000); } return super.dispatchTouchEvent(ev); } @Override protected void onUserLeaveHint() { super.onUserLeaveHint(); if (!isUserClickToLeave ) { //user press home button case. onHomePressed(); } isUserClickToLeave = false; } private onHomePressed() { //do something here. }