Comment détecter les clics de bouton Système "Applications récentes" (nid d'abeille+)
Je me demande Quelle méthode ce bouton appelle.
Mon jeu fait toujours une pause / reprend correctement sauf lorsque j'utilise ce bouton, il semble que ce bouton n'appelle pas les méthodes onPause()
et onResume()
d'une activité .
Cela fonctionne si je quitte le jeu, allez dans une autre fenêtre (comme celle sur l'image), puis utilisez ce bouton pour reprendre. Mais si je viens d'appuyer sur ce bouton, quand ingame, le jeu fait une pause mais le fil dosnt reprendre comme il le fait à chaque fois, le jeu genre de juste reste immobile à l'écran et scintille un peu.
Difficile à expliquer mais j'espère que je suis un peu clair, sinon, demandez!
7 réponses
Aucune des méthodes standard Activity Lifecycle n'est appelée lorsque le bouton" Applications récentes " est enfoncé. L'activité restera active après la liste des applications récentes popups. Grâce à la partie gauche semi-transparente de cette liste, vous pouvez même observer l'animation de l'application est toujours en cours d'exécution, si vous exécutez un jeu avec une animation qui n'a pas géré cette situation correctement. En fait, beaucoup de jeux dans Google Play n'ont pas géré cette situation correctement, même les bons, comme Angry Birds.
Le seul La méthode d'activité est appelée lorsque l'utilisateur ouvre la liste" Applications récentes " (ou en retourne) est onWindowFocusChanged avec le paramètre booléen hasFocus
. Lorsque l'utilisateur ouvre la liste de la méthode D'application récente onWindowFocusChanged()
appelée avec hasFocus
est égale à false
, et la même méthode appelée avec hasFocus
est égale à true
lorsque l'utilisateur appuie sur cette liste.
Pour détecter quand le bouton "Applications récentes" a été pressé, vous pouvez utiliser le service D'accessibilité. Vous devrez exécuter votre propre service D'accessibilité et recevoir des événements avec le type "TYPE_WINDOW_STATE_CHANGED" et vérifier le nom de la classe de l'événement.
- lisez à propos de Accessibility Service dans Android developer. Configurez votre propre service D'accessibilité, demandez l'autorisation de l'utilisateur.
- dans votre méthode Accessibility Service override
onAccessibilityEvent()
- Dans cette méthode, vous recevrez
AccessibilityEvent event
objet, cet objet contient toutes les informations nécessaires sur un événement qui vient de se produire sur votre appareil. -
Nous sommes intéressés par le ClassName. ClassName peut parfois être null alors n'oubliez pas != vérification nulle. Les noms des paquets de la fenêtre des applications récentes varient en fonction de la version D'Android:
- Android 4.1: "com.Android.interne.politique.impl.RecentApplicationsDialog "
- Android 4.2-4.4: "com.Android.systemui.récent.RecentsActivity "
- Android 5.0 - 7.1: "com.Android.systemui.récent.RecentsActivity" (la lettre " s " a été ajoutée)
Je ne connais pas le nom de classe pour les appareils plus anciens mais je ne pense pas que quelqu'un les maintienne en 2017;)
Donc, vous aurez quelque chose comme ceci:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.getClassName() == null)
return;
String className = String.valueOf(event.getClassName());
if (className.equals("com.android.internal.policy.impl.RecentApplicationsDialog")
|| className.equals("com.android.systemui.recent.RecentsActivity")
|| className.equals("com.android.systemui.recents.RecentsActivity")){
//Recent button was pressed. Do something.
}
}
Je l'ai testé sur les appareils réels suivants: LG, Nexus, Sony et les appareils virtuels: Motorola, Samsung.
Si quelqu'un connaît une exception pour ces noms de classe, envoyez-moi un ping.
J'ai fait face à un problème similaire, donc, je devais savoir quand l'utilisateur appuie sur le bouton Applications récentes (bouton de touche de menu dans les anciennes versions d'android). après plusieurs heures de recherche je n'ai pas trouvé un événement à attraper lorsque le bouton d'accueil ou appuyez sur le bouton menu. j'ai trouvé qu'il faut plus de temps pour appeler onStop () lorsque l'utilisateur appuie sur le bouton d'accueil, donc je trouve une astuce pour distinguer ces boutons de remorquage relatifs au temps de réponse et en remplaçant deux méthodes:
@ Override
public void onUserLeaveHint() {
// do stuff
super.onUserLeaveHint();
userLeaveTime = System.currentTimeMillis() ;
isNotPower = true;
}
@ Override
public void onStop() {
super.onStop();
if (isNotPower) {
defStop = System.currentTimeMillis() - userLeaveTime;
if (defStop > 200 ) {
//home button
}
if (defStop < 200) {
//recent apps button
}
}
isNotPower = false;
}
- le paramètre isNotPower pour vérifier que le bouton d'alimentation n'est pas pressé-lorsque le bouton d'alimentation est pressé, la méthode onStop () est appelée mais pas th onUserLeaveHint ().
La meilleure façon que j'ai trouvée est d'écouter une Action appelée "ACTION_CLOSE_SYSTEM_DIALOGS".De Google docs:
action de diffusion: ceci est diffusé lorsqu'une action de l'utilisateur doit demander un boîte de dialogue système temporaire à fermer. Quelques exemples de système temporaire les boîtes de dialogue sont la fenêtre de notification-shade et la boîte de dialogue Tâches récentes .
Code de travail:
IntentFilter intentFilterACSD = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
//do what you want here
}
}
};
this.registerReceiver(broadcastReceiver, intentFilterACSD);
J'ai le même problème, j'ai résolu ce problème comme below.er
Enregistrer bouton cliquez sur diffusion pour la maison et RecentApp
InnerReceiver mReceiver = new InnerReceiver();
IntentFilter mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mReceiver, mFilter);
Maintenant code BroadcastReceiver
class InnerReceiver extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
// Home Button click
} else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
// RecentApp or Overview Button click
}
}
}
}
}
}
Mais N'oubliez pas de unregisterReceiver
BroadcastReceiver
Est-ce seulement le problème avec ce jeu? Ou est-ce avec chaque jeu que vous jouez?
À côté des onPause()
et onResume()
, Il y a un autre cycle appelé onStop()
. Peut-être y a-t-il des choses fondamentales qui sont faites ici. En appuyant sur ce bouton"windows-open", Le jeu n'entrera probablement pas dans l'état onStop
alors qu'en appuyant sur le bouton "home", il le fera.
Essayez celui-ci:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if (!hasFocus) {
Log.d("Focus debug", "Lost focus !");
}
}