代码路径:
android\frameworks\base\core\java\com\android\internal\app\ResolverActivity.java
private void rebuildList() {
if (mBaseResolveList != null) {
mCurrentResolveList = mBaseResolveList;
} else {
mCurrentResolveList = mPm.queryIntentActivities(
mIntent, PackageManager.MATCH_DEFAULT_ONLY
| (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0));
// Filter out any activities that the launched uid does not
// have permission for. We don't do this when we have an explicit
// list of resolved activities, because that only happens when
// we are being subclassed, so we can safely launch whatever
// they gave us.
if (mCurrentResolveList != null) {
for (int i=mCurrentResolveList.size()-1; i >= 0; i--) {
ActivityInfo ai = mCurrentResolveList.get(i).activityInfo;
int granted = ActivityManager.checkComponentPermission(
ai.permission, mLaunchedFromUid,
ai.applicationInfo.uid, ai.exported);
if (granted != PackageManager.PERMISSION_GRANTED) {
// Access not allowed!
mCurrentResolveList.remove(i);
}
}
}
}
int N;
if ((mCurrentResolveList != null) && ((N = mCurrentResolveList.size()) > 0)) {
// Only display the first matches that are either of equal
// priority or have asked to be default options.
ResolveInfo r0 = mCurrentResolveList.get(0);
for (int i=1; i<N; i++) {
ResolveInfo ri = mCurrentResolveList.get(i);
if (false) Log.v(
"ResolveListActivity",
r0.activityInfo.name + "=" +
r0.priority + "/" + r0.isDefault + " vs " +
ri.activityInfo.name + "=" +
ri.priority + "/" + ri.isDefault + N);
if (r0.priority != ri.priority ||
r0.isDefault != ri.isDefault) {
while (i < N) {
mCurrentResolveList.remove(i);
N--;
}
}
}
if (N > 1) {
ResolveInfo.DisplayNameComparator rComparator =
new ResolveInfo.DisplayNameComparator(mPm);
Collections.sort(mCurrentResolveList, rComparator);
}
mList = new ArrayList<DisplayResolveInfo>();
// First put the initial items at the top.
if (mInitialIntents != null) {
for (int i=0; i<mInitialIntents.length; i++) {
Intent ii = mInitialIntents[i];
if (ii == null) {
continue;
}
ActivityInfo ai = ii.resolveActivityInfo(
getPackageManager(), 0);
if (ai == null) {
Log.w("ResolverActivity", "No activity found for "
+ ii);
continue;
}
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
if (ii instanceof LabeledIntent) {
LabeledIntent li = (LabeledIntent)ii;
ri.resolvePackageName = li.getSourcePackage();
ri.labelRes = li.getLabelResource();
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
ri.icon = li.getIconResource();
}
Log.e(TAG,"ResolveListAdapter" + ri.resolvePackageName);
mList.add(new DisplayResolveInfo(ri,
ri.loadLabel(getPackageManager()), null, ii));
}
}
// Check for applications with same name and use application name or
// package name if necessary
r0 = mCurrentResolveList.get(0);
int start = 0;
CharSequence r0Label = r0.loadLabel(mPm);
mShowExtended = false;
// for (int i = 1; i < N; i++) {
// if (r0Label == null) {
// r0Label = r0.activityInfo.packageName;
// }
// //Log.e(TAG,"r0Label" + r0.activityInfo.packageName);
// ResolveInfo ri = mCurrentResolveList.get(i);
// CharSequence riLabel = ri.loadLabel(mPm);
// if (riLabel == null) {
// riLabel = ri.activityInfo.packageName;
// }
// if (riLabel.equals(r0Label)) {
// continue;
// }
// processGroup(mCurrentResolveList, start, (i-1), r0, r0Label);
// r0 = ri;
// r0Label = riLabel;
// start = i;
// }//delete by wangjian 2014.06.19
// // Process last group
// processGroup(mCurrentResolveList, start, (N-1), r0, r0Label);
//******add by wangjian 2014.06.19*****//
if(N == 2){
ResolveInfo r1 = mCurrentResolveList.get(1);
CharSequence r1Label = r1.activityInfo.packageName;
if(r1 != null && r1Label != null){
//Log.v(TAG,"r1Label:" + r1.activityInfo.name);
//Log.v(TAG,"r1Label:" + r1.activityInfo.packageName);
processGroup(mCurrentResolveList, 1, 1, r1, r1Label);
}
}else{
// Log.v(TAG,"r0Label:" + r0.activityInfo.name);
//Log.v(TAG,"r0Label:" + r0.activityInfo.packageName);
processGroup(mCurrentResolveList, 0, 0, r0, r0Label);
}
//***********add code end*************//
}
}
ResolveInfo r1 = mCurrentResolveList.get(1);//从列表中获得自己的启动项
CharSequence r1Label = r1.activityInfo.packageName;//得到自己启动项的包名
ps:以上方法只适合存在两个启动项,一个是默认的系统启动项,一个是自己的app。
关键是这个方法需要注意:processGroup(mCurrentResolveList, 1, 1, r1, r1Label);
这个方法的实现:
private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
CharSequence roLabel) {
// Process labels from start to i
Log.e(TAG, "processGroup");
int num = end - start+1;
if (num == 1) {//如果num为1默认的把参数roLabel作为启动项,我们要的就是这个效果,当有两个启动项时按下HOME键不要选择,默认的把我们的APP作为启动项.
// No duplicate labels. Use label for entry at start
mList.add(new DisplayResolveInfo(ro, roLabel, null, null));
} else {
mShowExtended = true;
boolean usePkg = false;
CharSequence startApp = ro.activityInfo.applicationInfo.loadLabel(mPm);
if (startApp == null) {
usePkg = true;
}
if (!usePkg) {
// Use HashSet to track duplicates
HashSet<CharSequence> duplicates =
new HashSet<CharSequence>();
duplicates.add(startApp);
for (int j = start+1; j <= end ; j++) {
ResolveInfo jRi = rList.get(j);
CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm);
if ( (jApp == null) || (duplicates.contains(jApp))) {
usePkg = true;
break;
} else {
duplicates.add(jApp);
}
}
// Clear HashSet for later use
duplicates.clear();
}
for (int k = start; k <= end; k++) {
ResolveInfo add = rList.get(k);
if (usePkg) {
// Use application name for all entries from start to end-1
mList.add(new DisplayResolveInfo(add, roLabel,
add.activityInfo.packageName, null));
} else {
// Use package name for all entries from start to end-1
mList.add(new DisplayResolveInfo(add, roLabel,
add.activityInfo.applicationInfo.loadLabel(mPm), null));
}
}
}
}