Question

I hope that this question will not have the same luck with this one.

I want to give my users the ability to close some applications which are in the background via a list. By applications in the background I mean applications that the user started and then press the home button, for example Internet Browser. I have managed to find the background applications via the ActivityManager (both getRunningAppProcesses and getRunningTasks will do the job). However there are some applications in the background which are important for the system to work (i.e. Phone, Launcher, Input Methods etc) and I don't want them in my list.

My question is: How can I distinguish them from the non Important ones. I don't want to use some kind of String checking / filtering (like contains(com.android) etc) because I want to exclude some Important 3rd party apps like non stock Launchers, Dialer, Messaging etc.

Everyone who owns a Galaxy S2 and have used the "Program Monitor Widget" will know what i mean.

Thank you very much for your time and efforts...

Was it helpful?

Solution

Well I finally came up with a function that checks if a running task may considered as an "Important" one. First of all we have to use the getRunningTasks function from the ActivityManager to get a list filled with ActivityManager.RunningTaskInfo objects and then we pass each of these objects to the following function to do the check. Hope this helps someone...

public boolean isRunningTaskImportant(ActivityManager.RunningTaskInfo taskinfo) {
    //What makes a running task important is somehow "fluid" but there are a few task categories
    //on which is safe to assume that they are important. These categories are:
    //1. If task has not any actual activities running. This is because these are not actuall running but they are frozen by the
    //   the system and they will be killed if needed. They are not Important but we do not want them in our running apps list.
    //2. Well known namespaces including our own if we want to
    //3. Home Launcher Applications
    //4. Phone Handling Applications

    boolean result = false;
    ComponentName bActivity = taskinfo.baseActivity;

    if (bActivity == null) return false; //<-- The task has no base activity so we ignore it...

    String pName = bActivity.getPackageName();

    if (taskinfo.numRunning == 0) {
        result = true;
    } else {
        if (pName.equalsIgnoreCase("com.android.phone")) {
            result = true;
        } else if (pName.equalsIgnoreCase("com.android.contacts")) {
            result = true;
        } else if (pName.equalsIgnoreCase("com.chdcomputers.powerpanel")) {
            result = true;
        } else {
            //Here we are checking if out task is a home launcher application.
            //This code is based on this question: http://stackoverflow.com/questions/3293253/getting-list-of-installed-apps-easy-but-how-to-launch-one-of-them
            Log.d(TAG, "isRunningTaskImportant checking for launchers");
            Intent launchersIntent = new Intent(Intent.ACTION_MAIN, null); 
            launchersIntent.addCategory(Intent.CATEGORY_HOME);
            List<ResolveInfo> list = cx.getPackageManager().queryIntentActivities(launchersIntent,0); 
            boolean found = false;

            for (ResolveInfo ri : list){
                if (!found){
                    Log.d(TAG, "isRunningTaskImportant checking launcher app: " + ri.activityInfo.applicationInfo.packageName);
                    found = pName.equalsIgnoreCase(ri.activityInfo.applicationInfo.packageName);
                }
                if (found) break;
            }

            result = found;

            if (!found) {
                //Finaly we are going to check if out task is a Phone Handling application
                //The idea behind that is to check for what kind of permissions the application wants
                //In my opinion any "serious" phone handling app should ask for, at least, the following 9 permissions:
                //CALL_PHONE, CALL_PRIVILEGED, READ_CONTACTS, WRITE_CONTACTS, SYSTEM_ALERT_WINDOW, READ_PHONE_STATE,
                //MODIFY_PHONE_STATE, PROCESS_OUTGOING_CALLS, RECEIVE_BOOT_COMPLETED
                //So if the application asks for those permissions we can assume that is a phone handling application...

                Log.d(TAG, "isRunningTaskImportant checking possible phone app: " + pName);

                try {
                    PackageInfo pi = cx.getPackageManager().getPackageInfo(pName,PackageManager.GET_PERMISSIONS);
                    String[] perms = pi.requestedPermissions;

                    if (perms == null) {
                        result = false;
                    } else {
                        int pCount = 0;
                        for (String perm : perms) {
                            if (perm.equalsIgnoreCase("android.permission.CALL_PHONE")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.CALL_PRIVILEGED")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.READ_CONTACTS")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.WRITE_CONTACTS")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.SYSTEM_ALERT_WINDOW")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.READ_PHONE_STATE")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.MODIFY_PHONE_STATE")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.PROCESS_OUTGOING_CALLS")) {
                                pCount++;
                            } else if (perm.equalsIgnoreCase("android.permission.RECEIVE_BOOT_COMPLETED")) {
                                pCount++;
                            }
                        }
                        result = (pCount == 9);
                    }
                } catch (Exception ex) {
                    Log.e(TAG, "isRunningTaskImportant checking possible phone app ERROR: " + ex.getMessage());
                    result = false;
                }
            } 
        }
    }

    return result;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top