Je me demande quelle méthode ce bouton appelle.
Mon jeu se met toujours en pause/reprend correctement, sauf lorsque j'utilise ce bouton. Il semble que ce bouton n'appelle pas les méthodes onPause()
et onResume()
d'un Activity . Cela fonctionne si je quitte le jeu, allez dans une autre fenêtre (comme celle sur la photo), puis utilisez ce bouton pour reprendre. Mais si j'appuie simplement sur ce bouton, lorsque le jeu est en jeu, le jeu s'interrompt mais le thread ne reprend pas comme il le fait toutes les deux fois.
Difficile à expliquer mais j'espère être clair, sinon, demandez!
Aucune des méthodes Activity Lifecycle standard n'est appelée lorsque le bouton "Applications récentes" est enfoncé. L'activité restera active après la liste des popups des applications récentes. Dans la partie gauche semi-transparente de cette liste, vous pouvez même observer que l'animation de l'application est toujours en cours d'exécution si vous exécutez un jeu avec une animation qui ne gère pas cette situation correctement. En fait, de nombreux jeux sur Google Play ne géraient pas cette situation correctement, même les meilleurs, comme Angry Birds.
La seule méthode Activity appelée lors de l'ouverture de la liste des applications récentes (ou à partir de celle-ci) est onWindowFocusChanged avec le paramètre booléen hasFocus
. Lorsque l'utilisateur ouvre la liste de la méthode App récente onWindowFocusChanged()
appelée avec hasFocus
est égale à false
et que la même méthode appelée avec hasFocus
est égale à true
lorsque l'utilisateur appuie sur Retour dans cette liste.
Pour détecter quand le bouton 'Applications récentes' a été actionné, vous pouvez utiliser le service d'accessibilité. Vous devrez exécuter votre propre service d'accessibilité et recevoir des événements de type "TYPE_WINDOW_STATE_CHANGED" et vérifier le nom de la classe de l'événement.
onAccessibilityEvent()
AccessibilityEvent event
, qui contient toutes les informations nécessaires sur un événement qui vient de se produire sur votre périphérique.Nous sommes intéressés par le ClassName. ClassName peut parfois être null alors n'oubliez pas! = Null check. Les noms de package de la fenêtre Applications récentes varient en fonction de la version d'Android:
Je ne connais pas le nom de classe des appareils plus anciens, mais je ne pense pas que quelqu'un les conserve en 2017;)
Donc, vous aurez quelque chose comme ça:
@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 le même problème, j'ai résolu ce problème comme ci-dessous.er
Bouton Enregistrer, cliquez sur Diffuser pour Accueil et RecentApp
InnerReceiver mReceiver = new InnerReceiver();
IntentFilter mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mReceiver, mFilter);
Maintenant le 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 ne pas oublié de unregisterReceiver
BroadcastReceiver
J'ai rencontré un problème similaire, donc, je devais savoir quand l'utilisateur appuierait sur le bouton des applications récentes (bouton de menu dans les anciennes versions d'Android). Après plusieurs heures de recherche, je n'ai trouvé aucun événement à saisir lorsque vous appuyez sur le bouton d'accueil ou sur le bouton de menu. j’ai trouvé qu’il fallait plus de temps pour appeler onStop () lorsque l’utilisateur appuyait sur le bouton d’accueil;
@Passer outre
public void onUserLeaveHint() {
// do stuff
super.onUserLeaveHint();
userLeaveTime = System.currentTimeMillis() ;
isNotPower = true;
}
@Passer outre
public void onStop() {
super.onStop();
if (isNotPower) {
defStop = System.currentTimeMillis() - userLeaveTime;
if (defStop > 200 ) {
//home button
}
if (defStop < 200) {
//recent apps button
}
}
isNotPower = false;
}
La meilleure façon que j'ai trouvée est d'écouter l'action de diffusion intitulée "ACTION_CLOSE_SYSTEM_DIALOGS" .Dans les documents Google:
Action de diffusion: cette action est diffusée lorsqu'une action de l'utilisateur doit demander qu'une boîte de dialogue système temporaire soit rejetée. Quelques exemples de boîtes de dialogue système temporaires sont les suivantes: notification window-shade et les 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);
essaye celui-là:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if (!hasFocus) {
Log.d("Focus debug", "Lost focus !");
}
}
Est-ce seulement le problème avec ce jeu spécifique? Ou est-ce à chaque jeu que vous jouez?
À côté des onPause()
et onResume()
, il existe un autre cycle appelé onStop()
. Peut-être y a-t-il des choses fondamentales qui se font ici. En appuyant sur ce bouton "windows-open", le jeu ne passera probablement pas à l'état onStop
-, alors qu'il sera appuyé sur le bouton "home".
J'ai écrit une application qui montre sans ambiguïté le comportement de la clé recent-apps/recents en ce qui concerne les activités et les fragments.
(Toute assertion que des événements de cycle de vie normaux ne sont pas déclenchés par cette clé est manifestement fausse.)
Dans onCreate()
, le Activity principal initialise un tableau pour la journalisation de tous les événements de cycle de vie Activity connus et déclenche également le fragment principal à côté de lui dans un second FrameLayout.
Dans onAttach()
, le Fragment principal initialise un tableau séparé pour la journalisation de tous les événements de cycle de vie Fragment connus.
À des fins de journalisation, Activité et Fragment traitent onWindowFocusChanged()
comme un autre événement du cycle de vie.
Les événements consignés étant horodatés, une indication de "pause" de l'utilisateur peut être donnée lors du rendu (et le rendu a lieu dans onWindowFocusChanged()
quand hasFocus==true
).
Voici ce que l'utilisateur voit au démarrage de l'application de test:
Après quelques secondes, l'utilisateur appuie sur recent-apps, attend quelques secondes, puis appuie à nouveau pour voir la vérité:
NB: Si, au lieu d'utiliser le bouton recent-apps, l'expérience est répétée en: (a) appuyant sur le bouton marche/arrêt de la tablette (b) en appuyant sur le bouton Démarrer 2e activité (c), etc., les résultats sont identiques.
Réponse à l'OP:
Apparemment, il n'y a pas de code capable de détecter le fait d'appuyer sur la touche des applications récentes!
Mais cela n'a pas d'importance, car l'application doit quand même gérer correctement les événements de cycle de vie associés.