さて、私はついに、実行中のタスクが「重要な」タスクと見なされるかどうかをチェックする関数を思いつきました。まず、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;
}