How to know how much time has a user spent in my Android App?


#1

I want to know how much time does a user spend in my app, i.e. how active is a user in my App.

Please do let me know if someone has implemented the same in your app and how you guys have leveraged CleverTap for its analytics.


How to find particular user's engagement statistic
#2

Hi,

You can write this simple code in your Android app -

  1. Write an application lifecycle callback class in your app -

     public class MyApplicationLifeCycleCallback  {
         private static boolean registered = false;
         private static long appLastSeen=0;
         private static Runnable sessionTimeoutRunnable = null;
         private static final Handler handlerUsingMainLooper = new 
         Handler(Looper.getMainLooper());
    
          @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
         public static synchronized void register(android.app.Application application) {
    
             if (registered) {
                 Log.e("MyApplication","Lifecycle callbacks have already been registered");
                 return;
             }
    
             final CleverTapAPI wr;
    
             try {
                 wr = CleverTapAPI.getInstance(application.getApplicationContext());//Initialize 
                 CleverTap
             } catch (CleverTapException e) {
                 return;
             }
    
             registered = true;
             application.registerActivityLifecycleCallbacks(
                     new android.app.Application.ActivityLifecycleCallbacks() {
    
                         @Override
                         public void onActivityCreated(Activity activity, Bundle bundle) {
                             CleverTapAPI.setAppForeground(true);
                             try {
                                 wr.event.pushNotificationEvent(activity.getIntent().getExtras());//Handle push notifcations
                             } catch (Throwable t) {
                                 // Ignore
                             }
                             try {
                                 Intent intent = activity.getIntent(); //Handle deep links
                                 Uri data = intent.getData();
                                 wr.pushDeepLink(data);
                             } catch (Throwable t) {
                                 // Ignore
                             }
                         }
    
                         @Override
                         public void onActivityStarted(Activity activity) {
                         }
    
                         @Override
                         public void onActivityResumed(Activity activity) {
                             try {
                                 wr.activityResumed(activity);
                                 appLastSeen = System.currentTimeMillis();
                                 if(sessionTimeoutRunnable!=null)
                                     handlerUsingMainLooper.removeCallbacks(sessionTimeoutRunnable);
                             } catch (Throwable t) {
                                 // Ignore
                             }
                         }
    
                         @Override
                         public void onActivityPaused(Activity activity) {
                             try {
                                 wr.activityPaused(activity);
                                 final long now = System.currentTimeMillis();
                                 // Create the runnable, if it is null
                                 if (sessionTimeoutRunnable == null)
                                     sessionTimeoutRunnable = new Runnable() {
                                         @Override
                                         public void run() {
                                             HashMap<String, Object> sessionTime = new HashMap<String, Object>();
                                             sessionTime.put("Session Time", (System.currentTimeMillis() - appLastSeen)/1000);//Convert milliseconds to seconds
                                             sessionTime.put("Session Date", new Date());
                                             cleverTapAPI.event.push("Session stopped",sessionTime);
                                             appLastSeen = 0;
                                         }
                                     };
                                 handlerUsingMainLooper.postDelayed(sessionTimeoutRunnable,
                                         Constants.SESSION_LENGTH_MINS * 60 * 1000);
                             } catch (Throwable t) {
                                 // Ignore
                             }
                         }
    
                         @Override
                         public void onActivityStopped(Activity activity) {
    
                         }
    
                         @Override
                         public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    
                         }
    
                         @Override
                         public void onActivityDestroyed(Activity activity) {
    
                         }
                     }
    
             );
             Log.v("MyApplication","Activity lifecycle callback successfully registered");
         }
     }
    
  2. In your Application class call the above before super.OnCreate() like this -MyApplicationLifeCycleCallback.register(this)

  3. In the Dashboard, search event “Session Stopped” with the event property as the Session Time to get the total time the user has spent on the app. You can also search for the Activity name and get the time spent by the user on each Activity as well.

Hope this helps! :slight_smile:


How to track Session time in CleverTap?
App session according to app travel
#3

@Darshan

Can you tell, What is SESSION_LENGTH_MINS in the code?
and can we do
wr.event.push("Session stopped",sessionTime);

instead of

cleverTapAPI.event.push("Session stopped",sessionTime);


#4

Hi @sameer

Constants.SESSION_LENGTH_MINS is just a constant which you can set to any number, if you set it to 1, then the following line of code will be equivalent to 1 minute, if the value is set to 2 then it will be 2 minutes and so on -

Constants.SESSION_LENGTH_MINS * 60 * 1000

And yes you can use wr.event.push("Session stopped",sessionTime); if the wr in your code is the instance of CleverTapAPI.java. In the above code I have initialized the CleverTap SDK instance like this -

CleverTapAPI cleverTapAPI = CleverTapAPI.getInstance(this)

and hence I have used the code as cleverTapAPI.event.push("Session stopped",sessionTime);

Hope this answers your question! :slight_smile:


#5

Hi @Darshan thanks for this answer, one question though is the onActivityStarted() code needed since it is anyway being called in ActivityLifeCycleCallback class provided by Clevertap sdk being run before App’s super.onCreate()?


#6

Hi @Sanket_Vetkoli

This approach replaces the need for registering CleverTap’s ActivityLifecycleCallback with your own so that you can compute the time spent by a user on the app. Obviously, if you use this approach then there is no need to register CleverTap’s ActivityLifecycleCallback. The above code ensures that in your custom ActivityLifecycleCallback you also call the methods CleverTap requires to function normally.

Hope this answers your question.


#7

It does not work like need. According to above scenario that you mentioned to implement onPause method will be execute as the Recent app button clicked from device, but user has not closed application actually. It will create event in this case. According to requirement event should be created as the application closed which not in scope .


#8

@Rakesh_Kumar Whenever a user is done using the app, he/she always presses the home button which sends the app to the background first and then the user tends to kill the app from the Recent Screens. So the calling of onPause is inevitable and hence we calculate the session time and raise the event in onPause rather than onDestroy
onDestroy is called when the app is killed but one doesn’t know for sure if the app was destroyed by the user or the Android OS itself (as there are no callbacks) and hence it is best practice to do tasks related to the closing of the app in onPause rather than in onDestroy


#9

@Darshan Thanks for reply . User going to close the app from recent then onDestroy method will be called . But if user pressed the home button and there user see the list of recent applications that were opened , none of them application closed but have all recent application are showing on stack then onPause method will be called and here i can make an event of Session . But actually user has not closed the application . Then it is not way to make the Session with the event because application not yet closed . I have to check how much user has used app and for this it can not be implemented.


#10

@Rakesh_Kumar We do not advise to raise the Session event in the onDestroy method as the app gets killed and that event might never reach CleverTap and you would never be able to calculate the total time spent by the user in your app. Therefore, we advise you to raise the event in onPause because if the app is not killed and the user comes back then onResume will take care of the counter and if the app gets killed raising the event in onPause will at least help you in calculating average time spent by a user on your app. Hope this helps :slight_smile:


#11

@Darshan Well that’s not a way to implement this thing and will not be counted as Session end or finished with only onPause. If user has pressed the home button then there will show list of recent apps that i mentioned in previous comment and if the user gets back to app then whole session will be affect and would not be work . User has not killed or closed app and came back from recent then its wont be work with this scenario like need to implement. Thanks :slight_smile: :slight_smile:


#12

@Darshan can we also track When the user exits the App/Website, using clevertap?


#13

@Sanidhya_Chauhan It is difficult to tell when the user exits the app, we can only when the user puts the app in the background. This is because the user can manually kill the app or the Android OS on the device can kill the app. There is no callback for both. Hence, calculating the session time in the onPause() method is the only way to know. Also website is a different technology altogether and hence I don’t know how to calculate when a user exits a website


#14

@Darshan In the latest version of the sdk i.e. 3.4.0 CleverTapAPI.activityResumed() and activityPaused() have private access. How should I change the above mentioned solution by you to make it compute session time in the latest sdk?


#15

Got it thanks CleverTapAPI.onActivityResumed(activity);