Android app start and end event

I have an app which track user activity on app which include time etc, Now if user has opened the app, It will start an session and till user in this app , his session will continue, He can switch to multiple activity. Now meantime he switches to another app, His session logging should be stopped and written down to file

What I tried

  • How to downgrade my SDK Version?
  • checkSelfPermission method is not working in targetSdkVersion 22
  • TextView ellipsize and broken symbols
  • Percent color in Android for Material Design
  • Android - Share browser url to app
  • Deep link into an app while the app is already running in the background
  • I created one base activity and
    On resume event if counter is zero, I start session and increment counter and
    On stop event , i decrement counter and if counter is zero, I stop session

    But this will not calculate actual problem of tracking as android doesn’t stop activity as user switch to another app.

    So is there any way to achieve such thing.

    Additional:

    If we can get whether app activity is active on screen so event can be used to start or end session.

    Related posts:

    Android TextView Justify Text
    Android OpenGL demo “No config chosen”
    How to update ListView on scrolling while retrieving data from server in Android?
    How to set text of google api's dialog in application's default language
    How often do Market app statistics update?
    Camera Force Closing issue in Samsung Galaxy S3 version 4.1.1
  • using blobstore with google cloud endpoint and android
  • Read /dev/input/event in android via Java programming language
  • Grid of images inside ScrollView
  • JaCoCo returning 0% Coverage with Kotlin and Android 3.0
  • Android: How to create slide (on/off) button
  • Android hide soft keyboard IME
  • 3 Solutions collect form web for “Android app start and end event”

    I can think of two ways of doing it:

    Option 1:

    You can create a service which scans for the current application on the foreground and see if it is your activity. Here is some code you can use, I took it from another answer:

    There’s an easy way of getting a list of running tasks from the
    ActivityManager service. You can request a maximum number of tasks
    running on the phone, and by default, the currently active task is
    returned first.

    Once you have that you can get a ComponentName object by requesting
    the topActivity from your list.

    Here’s an example.

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

    You will need the following permission on your manifest:

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

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

    You can call this every one second or less to detect if your app is still active. Please note that it is a deprecated and is not recommended for using for this kind of things, according to official documentation:

    getRunningTasks()

    Note: this method is only intended for debugging and presenting task
    management user interfaces. This should never be used for core logic
    in an application, such as deciding between different behaviors based
    on the information found here. Such uses are not supported, and will
    likely break in the future. For example, if multiple applications can
    be actively running at the same time, assumptions made about the
    meaning of the data here for purposes of control flow will be
    incorrect.


    Option 2:

    The second option is to create a class that extends Application with a flag, for example isAppRunning, which will be true or false according if your application is on the foreground or not:

    public class MyAppContext extends Application {
    
       public boolean isAppRunning = true;
    
       public void setIsAppRunning(boolean v){
          isAppRunning = v;
       }
    
       public boolean isAppRunning(){
          return isAppRunning;
       }
    
    }
    

    Then on your AndroidManifest.xml you have to add this class so it will be used when your application starts. Just add android:name=".MyAppContext" under the application tag:

    <application
            android:name=".MyAppContext"
    

    Now in every activity that you have you should override onResume() and onPause() and set the flag to the corresponding value:

    class BaseActivity extends Activity {
    
    
        @Override
        protected void onResume() {
            super.onResume();
            ((MyAppContext)getApplication()).setIsAppRunning(true);
        }
    
        @Override
        protected void onPause() {
            ((MyAppContext)getApplication()).setIsAppRunning(false);
            super.onPause();
        }
    }
    

    On this way every time you start an Activity the value of isAppRunning in MyAppContext will be true, when you exit the Activity it will be false but if another Activity opens (for example if you pressed the back button so you are returning to the previous activity) the value will be immediately true again.

    When you finally finish all your Activities none of the onResume() methods will be called and all the onPause() methods will be called so isAppRunning will be false and you know your Activity is no longer on the foreground.

    So resuming, if isAppRunning is true your application is on the foreground (start the session tracking) otherwise it’s gone (stop the session tracking). You can create a Timer in MyAppContext class to check the value of isAppRunning periodically, so it would be:

    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 () { ... };
    
    }
    

    You should modify timerRate according to the precision you want to get in your session tracking.

    Extend all your Activities from BaseActivity like below. This is the best option for you as onPause and onResume methods are guaranteed to be called whenever your Activities show up or go away from phone screen.

    class BaseActivity extends Activity {
    
    
        @Override
        protected void onResume() {
            super.onResume();
            // Start Logging
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            // End Logging
        }
    }
    

    You need to look into Activity lifecycles on Android.

    What you need is onPause – see the documentation here

    I would also mention that onPause is fired even when switching between multiple activities, so you’d need to track when it’s pausing to go to another screen.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.