Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find list of application accessed by user in a Interval using a background job?

I want to find out the list of apps accessed by user in a particular time interval (ex: 5min), from a background job? Is this possible on a non-rooted android phone? If possible I'm very much interested in knowing the answer as it will be a great learning about android.

like image 275
Kishor Avatar asked Dec 03 '14 10:12

Kishor


1 Answers

Update:

In android 5.0 an alternative of getRecentTasks() method is getAppTasks.

Code Sample:

private void listTasks() throws PackageManager.NameNotFoundException {
  ActivityManager mgr = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.AppTask>  tasks = mgr.getAppTasks();
  String packagename;
  String label;
  for (ActivityManager.AppTask task: tasks){
    packagename = task.getTaskInfo().baseIntent.getComponent().getPackageName();
    label = getPackageManager().getApplicationLabel(getPackageManager().getApplicationInfo(packagename, PackageManager.GET_META_DATA)).toString();
    Log.v(TAG,packagename + ":" + label);
  }
}

Original Answer:

Introduction

The ActivityManager class provides two methods that returns such an information. Choosing getRecentTasks or getRunningTasks method would be appropriate since the returned tasks list is not our goal anyway. but, It will be used as a reference point on the way to determine the desired list.

Code Sample:

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RecentTaskInfo> activitys = activityManager.getRecentTasks(Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
for (int i = 0; i < activitys.size(); i++) {
    RecentTaskInfo activity = activitys.get(i);
    activity.baseIntent.getComponent().getPackageName();
}

Filtering: This list includes all type of tasks including system tasks.

Code Sample:

if (activity.baseIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
    // This is an application.
    getPackageManager()
        .getApplicationLabel(getPackageManager()
        .getApplicationInfo(activity.baseIntent.getComponent()
        .getPackageName(), PackageManager.GET_META_DATA)); // application name
}

This is the same list that will display on long pressing the home button.

Abstract Approach: (Explanation comes later)

To determine the desired list within the specified time that we will call (period). The recent tasks list will be asked for in the beginning of the period and after each smaller period within the period that we will call interval.

The recent apps. list fetched after the first interval will contain three type of apps. Old-apps, which are not in our interest, New-launched and Re-launched apps. The reason behind choosing the abstract approach is detecting the Re-launched apps.

Detecting New-launched Apps:

Those are the apps. that simply didn't appear in the very first fetched list. (before the period).

Explanation by examples why this approach:

  • It would be a great idea to consider any app. appeared before your app. in a later fetched list a re-launched app. since when we started the operation, which is from inside the app, your app. was on top of the list.

enter image description here

  • But, your app. may step down from top and gets back to it within the interval time. (Facebook > Twitter > Your App).

enter image description here

  • In a later fetched list another app. may get on top. taking it as a reference will fail too for the same reason your app. failed as a reference.

Winning Approach:

The list fetched before an interval will be the reference for the list fetched after the interval. the re-launched apps. would be the apps. appeared before the first-ordered-sub-list(fosl).

enter image description here

All the apps. before the fosl are re-launched not only What's app. And, It can be proven easily. There is no way to rearrange the apps on top of the fosl in a way that some of them may have been re-launched without the fosl get changed (get bigger to include more apps). you can exercise it.

fosl approach will work too even if user removed some of the apps. from the list manually within the interval. only removed apps will not be detect if they didn't got detected in a previous interval. but, it will not affect the fosl approach for the rest in the list. same thing if user cleared all the list, only the cleared apps. will not detected and not the ones launched after within the same interval.

Why intervals? because for such a long period user can open and relaunch apps. then, clear the list or remove some.

Small intervals would also make it so hard on the user to open any top sublist with the same order again which is the only weakness of the fosl approach.

Sample Code: (fosl)

public int getIndexOfFirstAppBeforeFOSL(ArrayList<App> recentApps) {
    int i=previousRecentApps.size()-1, j = recentApps.size()-1;
    for (; i>=0 && j>=0 ; i--) {
        App app = previousRecentApps.get(i);
        if (app.equals(recentApps.get(j))) {
            j--;
        } else {
            // this application got re-launched and therefore it changed it place in list.
            // or removed manually by user.
        }
    }

    return j;
}

I created a GitHub project for the application. check it out, and report bugs if any.

Missing to detect one or two apps for the weakness we mentioned want really going to effect the research result your are getting from collecting apps. getting launched from a big number of user. if that what are you doing anyway. Otherwise, your app. can frequently get new launched app. and notify the user about it.

like image 179
hasan Avatar answered Nov 13 '22 03:11

hasan