好吧,我终于想出了一个功能,可以检查正在运行的任务是否可以被视为“重要”任务。首先,我们必须使用 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;
}