21

Zastanawiam się, jaką metodę wywołuje ten przycisk.Jak wykryć kliknięcia przycisku systemowego "Ostatnie aplikacje" (Honeycomb +)

enter image description here

Moja gra zawsze wstrzymuje/wznawia poprawnie z wyjątkiem kiedy użyć tego przycisku, jego wydaje się ten przycisk nie nazywają onPause() i onResume() sposoby na Activity. Działa, gdy wyjdę z gry, przejdź do innego okna (takiego jak na zdjęciu), a następnie użyj tego przycisku, aby kontynuować. Ale jeśli po prostu naciśniesz ten przycisk, podczas gry gra się zatrzyma, ale wątek dosnt wznowi się tak, jak robi się to co drugi raz, rodzaj gry po prostu stoi na ekranie i migocze trochę.

Trudno mi to wytłumaczyć, ale mam nadzieję, że nie jestem pewien, jeśli nie, zapytaj!

+1

To nie ma nic wspólnego z realizacją przycisku. Jest to błąd w grze jego implementacji. – DroidBender

+0

Ale działa tak, jak powinno, kiedy wyjdę z gry przez "dom" -przycisk ", a następnie wprowadź go ponownie przez ten" "okienko-przycisk". Jedyny czas, w którym to nie działa, to naciśnięcie przycisku "windows-open" w grze, a następnie natychmiastowe naciśnięcie okna gry. Musi to być jakaś różnica w sposobie wywołania 'onPause()' i 'onResume()' w porównaniu do tego, jak są normalnie wywoływane. –

Odpowiedz

21

Żadna ze standardowych metod Activity Lifecycle nie jest wywoływana po naciśnięciu przycisku "Ostatnie aplikacje". Aktywność pozostanie aktywna po liście ostatnich wyskakujących okienek aplikacji. Przez półprzezroczystą lewą część tej listy można nawet obserwować animację aplikacji, która wciąż działa, jeśli uruchomiłeś grę z animacją, która nie poradziła sobie z tą sytuacją poprawnie. W rzeczywistości wiele gier w Google Play nie poradziło sobie z tą sytuacją prawidłowo, nawet te dobre, takie jak Angry Birds.

Jedyna metoda Activity jest wywoływana, gdy użytkownik otwiera listę "Ostatnie aplikacje" (lub zwraca z niej) jest onWindowFocusChanged z parametrem boolean hasFocus. Gdy otwarta lista użytkowników dla metody Ostatnia aplikacja onWindowFocusChanged() wywoływana z hasFocus równa się false, i ta sama metoda wywoływana z hasFocus równa się true, gdy użytkownik naciska Back na tej liście.

+0

dziękuję, wyjaśniłeś to trochę :) zawsze dobrze znać maszynę, z którą współpracujesz. –

+1

Wygląda na to, że w Androidzie 4.4.4, onPause/onStop są wywoływane po naciśnięciu przycisku ostatnich aplikacji. – amram99

+1

Ale onWindowFocusChanged będzie również fałszywy, jeśli otworzysz inną aktywność w aplikacji, więc niekoniecznie pomoże to w zorientowaniu się, że został naciśnięty przycisk "Ostatnie aplikacje" (zwany również przyciskiem Przegląd). – Bourne

0

Czy to tylko problem z tą konkretną grą? A może w każdej grze, w którą grasz?

Oprócz onPause() i onResume(), istnieje inny cykl o nazwie onStop(). Może są tu robione pewne podstawowe rzeczy. Po naciśnięciu tego przycisku "windows-open", gra prawdopodobnie nie wejdzie do onStop -state, podczas gdy naciśnięcie przycisku "home" to zrobi.

+0

Dobra racja, spróbuję oznaczyć niektóre metody i zobaczyć, co się stanie. –

0

spróbować tego:

public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 

    Log.d("Focus debug", "Focus changed !"); 

    if (!hasFocus) { 
     Log.d("Focus debug", "Lost focus !"); 

    } 
} 
3

wychodził podobny problem, więc musiałem wiedzieć, kiedy nacisnąć przycisk Ostatnie aplikacje (klawisz menu przycisk w starych wersjach Androida) użytkownika. po kilku godzinach poszukiwań nie znalazłem zdarzenia do złapania po naciśnięciu przycisku home lub przycisku menu. I okazało się, że to potrwać dłużej niż zadzwonić OnStop(), kiedy nacisnąć przycisk home użytkownik, więc postać trick odróżnić tych przycisków holowniczych odnoszących się na czas reakcji i nadrzędnych dwóch metod:

@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; 
} 
  • parametr isNotPower to aby sprawdzić czy nie przycisk zasilania jest pressed- gdy przycisk zasilania nacisnął OnStop() wywoływana jest metoda, ale nie o th nUserLeaveHint().
2

Aby wykryć, kiedy przycisk "Ostatnie aplikacje" został naciśnięty, możesz użyć usługi dostępności.Musisz uruchomić własną usługę ułatwień dostępu i otrzymywać powiadomienia o typie "TYPE_WINDOW_STATE_CHANGED" i sprawdzać nazwę klasy wydarzenia.

  1. Przeczytaj o Accessibility Service w Androidzie. Skonfiguruj własną usługę ułatwień dostępu, poproś o pozwolenie od użytkownika.
  2. w usłudze Dostępność metody obejścia onAccessibilityEvent()
  3. W ten sposób otrzymasz AccessibilityEvent event przedmiot, cel ten zawiera wszystkie niezbędne informacje na temat zdarzenia, które właśnie się stało na swoim urządzeniu.
  4. Jesteśmy zainteresowani nazwą klasy. ClassName czasami może mieć wartość null, więc nie zapomnij o opcji! = Null check. Nazwy pakietów ostatnich aplikacji okno będzie się różnić w zależności od wersji Androida:

    • Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
    • Android 4.2 - 4.4: „com.android .systemui.recent.RecentsActivity”
    • Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity"("s" list został dodany)

nie wiem nazwę klasy dla starszych urządzeń ale nie sądzę, ktoś utrzymuje je w 2017 roku;)

więc trzeba będzie coś takiego:

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

Przetestowałem go na następujących rzeczywistych urządzeń: LG, Nexus, Sony i wirtualne urządzenia: Motorola, Samsung.

Jeśli ktoś zna wyjątki dla tych nazw klas, proszę o pingowanie mnie.

1

Najlepszym sposobem znalazłem jest listent do Broadcast akcję „ACTION_CLOSE_SYSTEM_DIALOGS” .Z Google docs:

Broadcast Działanie: Jest to broadcast gdy akcja użytkownik powinien zwrócić się okno System tymczasowy do odwołania. Niektóre przykłady okien dialogowych tymczasowego systemu to okno powiadomień i ostatnie okno dialogowe zadań.

kod robocza:

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); 
1

Mam ten sam problem, mam rozwiązany ten problem jako below.er

przycisk Rejestracja click audycji dla domu i RecentApp

InnerReceiver mReceiver = new InnerReceiver(); 
IntentFilter mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 
registerReceiver(mReceiver, mFilter); 

Teraz BroadcastReceiver code

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

ale nie zapomniał unregisterReceiver BroadcastReceiver

+1

Zrobiłem pełną implementację tutaj w Androidzie, aby reagować natywnie https://github.com/evanjmg/react-native-home-pressed/blob/master/android/src/main/java/com/evanjmg/HomeWatcher. Jawa – evanjmg

Powiązane problemy