1

我希望这个问题不会和这个问题一样好运

我想让我的用户能够通过列表关闭一些在后台的应用程序。后台应用程序是指用户启动然后按下主页按钮的应用程序,例如 Internet 浏览器。我设法通过 ActivityManager 找到了后台应用程序(getRunningAppProcesses 和 getRunningTasks 都可以完成这项工作)。然而,在后台有一些应用程序对系统工作很重要(即电话、启动器、输入法等),我不希望它们出现在我的列表中。

我的问题是:如何将它们与非重要的区别开来。我不想使用某种字符串检查/过滤(例如 contains(com.android) 等),因为我想排除一些重要的 3rd 方应用程序,例如非库存启动器、拨号器、消息传递等。

每个拥有 Galaxy S2 并使用过“节目监视器小部件”的人都会明白我的意思。

非常感谢您的时间和努力...

4

1 回答 1

0

好吧,我终于想出了一个功能,可以检查正在运行的任务是否可以被视为“重要”任务。首先,我们必须使用 ActivityManager 中的 getRunningTasks 函数来获取一个包含 ActivityManager.RunningTaskInfo 对象的列表,然后我们将这些对象中的每一个传递给以下函数进行检查。希望这可以帮助某人...

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;
}
于 2012-05-02T01:02:48.937 回答