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.
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:
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With