首页 > 代码库 > android 系统存在多个Launcher时,设置开机自动进入默认的Launcher

android 系统存在多个Launcher时,设置开机自动进入默认的Launcher

开机完成并解锁后,如果android系统存在多个Launcher,系统会弹出一个选择框让用户选择进入某个Launcher。如果用户不想选择,而是想直接进入某一个默认的Launcher,要怎么修改?
注意:此修改方法对Google Now Launcher(GoogleHome.apk)无效,因为此APP启动Activity的<intent-filter>中无<category android:name="android.intent.category.HOME" />这个选项。
 
下面以设置Google Launcher2作为默认启动的Launcher为例,
其package name 为 com.android.launcher
launcher activity name 为 com.android.launcher2.Launcher


1、请在PackageManagerService.java中的systemReady函数的最后中增加以下代码。
     if(isFirstBoot())
        {
   //ADD BEGIN 
    String examplePackageName = "com.android.launcher";  //请修改为需要设置的 package name
    String exampleActivityName = "com.android.launcher2.Launcher"; //请修改为需要设置的 launcher activity name  
    Intent intent=new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    final int callingUserId = UserHandle.getCallingUserId();
    
    List<ResolveInfo> resolveInfoList = queryIntentActivities(intent,null, PackageManager.GET_META_DATA,callingUserId);
    if(resolveInfoList != null){
      int size = resolveInfoList.size();
      for(int j=0;j<size;){
        final ResolveInfo r = resolveInfoList.get(j);
        if(!r.activityInfo.packageName.equals(examplePackageName)){ 
         resolveInfoList.remove(j);
         size -= 1;
      }else
      {
        j++;
      }
      }
      ComponentName[] set = new ComponentName[size];
      ComponentName defaultLauncher=new ComponentName(examplePackageName, exampleActivityName);
      int defaultMatch=0;
      for(int i=0;i<size;i++){
        final ResolveInfo resolveInfo = resolveInfoList.get(i);
        Log.d(TAG, resolveInfo.toString());
        set[i] = new ComponentName(resolveInfo.activityInfo.packageName,resolveInfo.activityInfo.name);
        if(defaultLauncher.getClassName().equals(resolveInfo.activityInfo.name)){
         defaultMatch = resolveInfo.match;
        }
      }
      Slog.e(TAG,"defaultMatch="+Integer.toHexString(defaultMatch));
      IntentFilter filter=new IntentFilter();
      filter.addAction(Intent.ACTION_MAIN);
      filter.addCategory(Intent.CATEGORY_HOME);
      filter.addCategory(Intent.CATEGORY_DEFAULT);
      
      addPreferredActivity2(filter, defaultMatch, set, defaultLauncher);
    }
    //ADD END
  }
2.在PackageManagerService.java中增加addPreferredActivity2函数。
public void addPreferredActivity2(IntentFilter filter, int match,
    ComponentName[] set, ComponentName activity) {
   Log.d("debug_default","addPreferredActivity2 is called.");
   // writer
   synchronized (mPackages) {     
       Slog.i(TAG, "Adding preferred activity " + activity + ":");
       filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
       mSettings.editPreferredActivitiesLPw(0).addFilter(
            new PreferredActivity(filter, match, set, activity, true));
       scheduleWriteSettingsLocked();     
   }
  }
3.修改PackageManagerService.java的函数findPreferredActivity
    
   (1) 对原来的removeMatches 增加判断条件,在launcher时不remove
      if(!(intent.getAction() != null && intent.getAction().equals(intent.ACTION_MAIN) && intent.getCategories()!=null && intent.getCategories().contains(intent.CATEGORY_HOME))) { //ADD          
       Slog.d(TAG,"launcher");      
      }else {
            if (removeMatches) {
                pir.removeFilter(pa);
                if (DEBUG_PREFERRED) {
                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
                }
                 break;
            }
       }
(2)
                        if (always && !pa.mPref.sameSet(query, priority)) {
                            Slog.i(TAG, "Result set changed, dropping preferred activity for "
                                    + intent + " type " + resolvedType);
                            if (DEBUG_PREFERRED) {
                                Slog.v(TAG, "Removing preferred activity since set changed "
                                        + pa.mPref.mComponent);
                            }
                            pir.removeFilter(pa);
                            // Re-add the filter as a "last chosen" entry (!always)
                            PreferredActivity lastChosen = new PreferredActivity(
                                    pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
                            pir.addFilter(lastChosen);
                            mSettings.writePackageRestrictionsLPr(userId);
                            return null;
                        }
上面这段修改为下面的内容:
                        if (always && !pa.mPref.sameSet(query, priority)) {
                           
       if(!(intent.getAction() != null && intent.getAction().equals(intent.ACTION_MAIN) && intent.getCategories()!=null && 
       
           intent.getCategories().contains(intent.CATEGORY_HOME))) { //ADD
        Slog.i(TAG, "Result set changed, dropping preferred activity for "
                                    + intent + " type " + resolvedType);
                            if (DEBUG_PREFERRED) {
                                Slog.v(TAG, "Removing preferred activity since set changed "
                                        + pa.mPref.mComponent);
                            }
       pir.removeFilter(pa);
       
                            // Re-add the filter as a "last chosen" entry (!always)
                            PreferredActivity lastChosen = new PreferredActivity(
                                    pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
                            pir.addFilter(lastChosen);
                            mSettings.writePackageRestrictionsLPr(userId);
                            return null;
       }
                        }
      Slog.i(TAG,"Result set not change, not drop preferred activity for special intent: "+intent);//ADD
                        // Yay! Either the set matched or we‘re looking for the last chosen




JB系列findPreferredActivity略有调整,见下面:
修改 packageManagerService.java (framework/base/services/java/com/android/server/pm/)的findPreferredActivity方法,将此方法比较靠后的一段代码:
if (!pa.mPref.sameSet(query, priority)) {
    Slog.i(TAG, "Result set changed, dropping preferred activity for " + intent + " type " + resolvedType);
    pir.removeFilter(pa); 
    return null;
}
 
修改为:
if (!pa.mPref.sameSet(query, priority)) {
    if(!(intent.getAction() != null && intent.getAction().equals(intent.ACTION_MAIN) && intent.getCategories()!=null &&
        intent.getCategories().contains(intent.CATEGORY_HOME)))  { //ADD
        Slog.i(TAG, "Result set changed, dropping preferred activity for "+ intent + " type " + resolvedType);
        pir.removeFilter(pa); 
        return null;
    } //ADD
    Slog.i(TAG,"Result set not change, not drop preferred activity for special intent: "+intent);//ADD
}
 
如果用户在设置->应用程序->管理应用程序->所有应用程序列表,找到之前设置的默认Launcher,并取消了默认值,系统会重新弹出launcher选择框。

android 系统存在多个Launcher时,设置开机自动进入默认的Launcher