2013-10-02 11 views
10

Mam aplikację, która śledzi aktywność użytkownika w aplikacji, która zawiera czas itp. Teraz, jeśli użytkownik otworzył aplikację, rozpocznie sesję i do czasu, aż użytkownik w tej aplikacji, jego sesja będzie kontynuowana, można przełączyć na wiele działań. Teraz międzyczasie przełącza się na inną aplikację, Jego rejestrowanie sesji powinny być zatrzymane i zapisane do plikuPoczątek i zakończenie aplikacji Android

co starałem

stworzyłem jedną działalność podstawową i W przypadku wznowienia, jeżeli licznik jest zero, zaczynam sesję i przyrost licznik i W zdarzeniu stop, licznik zmniejszania i licznik jest równy zeru, zatrzymuję sesję

Nie spowoduje to jednak obliczenia rzeczywistego problemu z śledzeniem, ponieważ Android nie przerywa aktywności jako użytkownik przełączający się do innej aplikacji.

Czy istnieje sposób na osiągnięcie czegoś takiego?

dodatkowe:

Jeśli możemy dostać czy aktywność aplikacja jest aktywna na ekranie tak, zdarzenie może być wykorzystane do rozpoczęcia lub koniec sesji.

Odpowiedz

0

Musisz zajrzeć do cyklu życia aktywności na Androidzie.

Co trzeba to - patrz dokumentacja here

Chciałbym również wspomnieć, że OnPause wypala nawet podczas przełączania między wieloma działaniami, więc trzeba by śledzić, kiedy to zatrzymując się, aby przejść do innego ekranu.

+0

, więc użycie opcji onPause nie spowoduje podania informacji o aplikacji dotyczącej przejścia na inną aplikację lub inną aktywność ... – Kasma

+0

Nie, to tylko część działań. Działa, działa, gdy aktywność nie jest już aktywna. Dzieje się tak, gdy użytkownik przełącza się do innej aplikacji, inna aplikacja zaczyna skupiać się na pierwszym planie (zauważyłem, że dzieje się tak, gdy dodasz słowo do słownika na klawiaturze), a nawet gdy urządzenie jest zablokowane przez użytkownika, lub czas oczekiwania na ekranie blokuje urządzenie. – EvilGeniusJamie

+0

ale jak śledzić, czy chodzi o inną aktywność ... – Kasma

5

mogę myśleć dwa sposoby prowadzenia go:

Wariant 1:

można stworzyć usługę, która skanuje dla bieżącej aplikacji na pierwszym planie i sprawdzić, czy to jest Twoja aktywność. Oto kod można użyć, wziąłem go z innej odpowiedzi:

Jest to prosty sposób na uzyskanie listę uruchomionych zadań z usługi ActivityManager. Możesz zażądać maksymalnej liczby zadań uruchomionych w telefonie, a domyślnie aktywne zadanie to zwrócone jako pierwsze.

Po uzyskaniu informacji o obiekcie ComponentName można poprosić o topActivity z listy.

Oto przykład.

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); 

    // get the info from the currently running task 
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 

    Log.d("topActivity", "CURRENT Activity ::" 
      + taskInfo.get(0).topActivity.getClassName()); 

    ComponentName componentInfo = taskInfo.get(0).topActivity; 
    componentInfo.getPackageName(); 

Potrzebne będą następujące pozwolenia na swoim manifeście:

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

Link odpowiedź: Android: How can I get the current foreground activity (from a service)?

można nazwać każdą jedną sekundę lub mniej, aby wykryć, czy aplikacji jest nadal aktywny.Należy pamiętać, że jest przestarzała i nie jest zalecana do korzystania z tego rodzaju rzeczy, według oficjalnej dokumentacji:

getRunningTasks()

Uwaga: metoda ta jest przeznaczona tylko do debugowania i prezentacji zadań zarządzanie interfejsami użytkownika. Nigdy nie powinno to być używane w logice rdzeniowej w aplikacji, na przykład podczas wybierania między różnymi zachowaniami opartymi na w odniesieniu do informacji znajdujących się tutaj. Takie zastosowania nie są obsługiwane i prawdopodobnie ulegną uszkodzeniu w przyszłości. Na przykład, jeśli wiele aplikacji może aktywnie działać w tym samym czasie, to założenia dotyczące znaczenia tych danych dla celów sterowania przepływem będą niepoprawne w przypadku .


Opcja 2:

Drugą opcją jest utworzyć klasę, która rozciąga Application z flagą, na przykład isAppRunning, który będzie prawda czy fałsz według jeśli aplikacja znajduje się na na pierwszym planie czy nie:

public class MyAppContext extends Application { 

    public boolean isAppRunning = true; 

    public void setIsAppRunning(boolean v){ 
     isAppRunning = v; 
    } 

    public boolean isAppRunning(){ 
     return isAppRunning; 
    } 

} 

Następnie na AndroidManifest.xml trzeba dodać do tej klasy tak będzie używany podczas swojej applic Rozpoczęcie ation. Wystarczy dodać android:name=".MyAppContext" pod tagiem aplikacji:

<application 
     android:name=".MyAppContext" 

Teraz w każdej działalności, które masz powinny przesłonić onResume() i onPause() i ustawić flagę do odpowiedniej wartości:

class BaseActivity extends Activity { 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     ((MyAppContext)getApplication()).setIsAppRunning(true); 
    } 

    @Override 
    protected void onPause() { 
     ((MyAppContext)getApplication()).setIsAppRunning(false); 
     super.onPause(); 
    } 
} 

Na ten sposób za każdym razem kiedy Rozpocznij działanie, wartość isAppRunning w MyAppContext będzie true, po wyjściu z Activity będzie to false, ale jeśli otworzy się inne działanie (na przykład, jeśli naciśniesz przycisk Wstecz, aby powrócić do poprzednia czynność) wartość będzie ponownie true ponownie.

Kiedy wreszcie zakończyć wszystkie swoje działania żadna z metod onResume() zostaną nazwane i wszystkie metody onPause() będzie nazwany tak isAppRunning będzie false i wiesz już swój Activity jest na pierwszym planie.

Tak więc wznawianie, jeśli isAppRunning jest true Twoja aplikacja znajduje się na pierwszym planie (uruchom śledzenie sesji) w przeciwnym razie zniknie (zatrzymaj śledzenie sesji). Można utworzyć Timer w MyAppContext klasę sprawdzić wartość isAppRunning okresowo, więc byłoby:

public class MyAppContext extends Application { 

    public boolean isAppRunning = true; 
    public final int timerRate = 500; // Execute timer task every 500mS 

    public void setIsAppRunning(boolean v){ 
     isAppRunning = v; 
    } 

    public boolean isAppRunning(){ 
     return isAppRunning; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Timer mTimer = new Timer(); 

     mTimer.scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      if(isAppRunning) startSesionTracking(); 
      else stopSesionTracking(); 
     } 
     }, 0, REFRESH_TIME); 
    } 

    private void startSesionTracking() { ... }; 
    private void stopSesionTracking() { ... }; 

} 

Należy zmodyfikować timerRate zgodnie z precyzją chcesz dostać w śledzeniu sesji.

+0

Jest to wycofana funkcja API i nie zawsze zwraca poprawną wartość. Jestem zmuszony do korzystania z tego w mojej aplikacji i to nie działa cały czas. Dokumentacja API wyraźnie wspomina o tym. –

+0

Tak, ale nie mogę myśleć o niczym innym, aby śledzić aktywność. – Andres

2

Rozszerz wszystkie swoje aktywności z BaseActivity, tak jak poniżej. Jest to najlepsza opcja dla ciebie, ponieważ funkcje onPause i onResume są gwarantowane, gdy tylko pojawią się Twoje Aktywności lub znikną z ekranu telefonu.

class BaseActivity extends Activity { 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     // Start Logging 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     // End Logging 
    } 
} 
+0

To jest najprostszy (i najlepszy) sposób na to, a także zalecane użycie dla większości zewnętrznych API, które tego wymagają (np. Flurry) –

0

1.Utwórz klasę o nazwie AppLifecycleTracker i wklej ją.

private class AppLifecycleTracker implements ActivityLifecycleCallbacks { 
      private int numStarted = 0; 
      private String TAG = "AppLifecycleTracker"; 


      private int numOfCreated = 0; 

      @Override`enter code here` 
      public void onActivityCreated(Activity activity, Bundle bundle) { 
       if (numOfCreated == 0) { 
        Log.d(TAG, "onActivityCreated: app started"); 
       } 
       numOfCreated++; 
       Log.d(TAG, "onActivityCreated: " + numOfCreated); 
      } 

      @Override 
      public void onActivityStarted(Activity activity) { 
       if (numStarted == 0) { 
        // app went to foreground 
        Log.d(TAG, "onActivityStarted: foreground"); 

       } 
       numStarted++; 


      } 

      @Override 
      public void onActivityResumed(Activity activity) { 

      } 

      @Override 
      public void onActivityPaused(Activity activity) { 

      } 

      @Override 
      public void onActivityStopped(Activity activity) { 
       numStarted--; 
       if (numStarted == 0) { 
        // app went to background 
        Log.d(TAG, "onActivityStarted: background"); 

       } 
      } 

      @Override 
      public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { 

      } 

      @Override 
      public void onActivityDestroyed(Activity activity) { 
       numOfCreated--; 
       Log.d(TAG, "onActivityDestroyed: " + numOfCreated); 
      } 
     } 

* w onActivityCreate jeśli numOfCreated = 0, to można powiedzieć, aplikacja została uruchomiona. * w onActivityDestroyed, jeśli numOfCreated = 0, możesz powiedzieć, że aplikacja jest zamknięta.

  1. Tworzenie klasy rozciągającą zastosowania, w onCreate dodać tę linię

    registerActivityLifecycleCallbacks (New AppLifecycleTracker());

  2. zestaw nazwa aplikacji jako klasa aplikacji w manifest.xml

to wszystko. Możesz ruszać.