android设置多个类似APP其中的一个为默认 设置默认launcher


05-09 17:01:13.547: I/ActivityManager(3003): START u0 {act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=https://www.baidu.com cmp=android/com.android.internal.app.ResolverActivity} from pid 5222
05-09 17:01:13.587: I/ActivityManager(3003): Start proc system:ui for activity android/com.android.internal.app.ResolverActivity: pid=15544 uid=1000 gids={41000, 3002, 3001, 3003, 1028, 1015, 1023, 1021, 3004, 3005, 1000, 3009, 1010}
05-09 17:01:14.557: I/ActivityManager(3003): Displayed android/com.android.internal.app.ResolverActivity: +975ms
复制代码

从ActivityManger输出Log可以知道是ResolverActivity处理app选择。

android\frameworks\base\core\java\com\android\internal\app\ResolverActivity.java

复制代码
protected void onCreate(Bundle savedInstanceState) {
        // Use a specialized prompt when we're handling the 'Home' app startActivity()
        final int titleResource;
        final Intent intent = makeMyIntent();
        final Set<String> categories = intent.getCategories();
        if (Intent.ACTION_MAIN.equals(intent.getAction())
                && categories != null
                && categories.size() == 1
                && categories.contains(Intent.CATEGORY_HOME)) {
            titleResource = com.android.internal.R.string.whichHomeApplication;//选择主屏幕应用
        } else {
            titleResource = com.android.internal.R.string.whichApplication;//选择要使用的应用:
        }

        onCreate(savedInstanceState, intent, getResources().getText(titleResource),
                null, null, true);
    }
复制代码
复制代码
 protected void onCreate(Bundle savedInstanceState, Intent intent,
            CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
            boolean alwaysUseOption) {
        setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
        super.onCreate(savedInstanceState);
        try {
            mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
                    getActivityToken());
        } catch (RemoteException e) {
            mLaunchedFromUid = -1;
        }
        mPm = getPackageManager();
        mAlwaysUseOption = alwaysUseOption;
        mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);

        AlertController.AlertParams ap = mAlertParams;

        ap.mTitle = title;

        mPackageMonitor.register(this, getMainLooper(), false);
        mRegistered = true;

        final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        mIconDpi = am.getLauncherLargeIconDensity();
        mIconSize = am.getLauncherLargeIconSize();

        mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList, mLaunchedFromUid);//获取APP列表

        int count = mAdapter.getCount();
        if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
            // Gulp!
            finish();
            return;
        } else if (count > 1) {
            ap.mView = getLayoutInflater().inflate(R.layout.resolver_list, null);
            mListView = (ListView) ap.mView.findViewById(R.id.resolver_list);
            mListView.setAdapter(mAdapter);
            mListView.setOnItemClickListener(this);
            mListView.setOnItemLongClickListener(new ItemLongClickListener());

            if (alwaysUseOption) {
                mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            }
        } else if (count == 1) {
            startActivity(mAdapter.intentForPosition(0));
            mPackageMonitor.unregister();
            mRegistered = false;
            finish();
            return;
        } else {
            ap.mMessage = getResources().getText(R.string.noApplications);
        }

        setupAlert();

        if (alwaysUseOption) {
            final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
            if (buttonLayout != null) {
                buttonLayout.setVisibility(View.VISIBLE);
                mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
                mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
            } else {
                mAlwaysUseOption = false;
            }
            // Set the initial highlight if there was a preferred or last used choice
            final int initialHighlight = mAdapter.getInitialHighlight();
            if (initialHighlight >= 0) {
                mListView.setItemChecked(initialHighlight, true);
                onItemClick(null, null, initialHighlight, 0); // Other entries are not used
            }
        }
    }
复制代码

点击“始终”按钮,设置默认程序

复制代码
public void onButtonClick(View v) {
        final int id = v.getId();
        startSelected(mListView.getCheckedItemPosition(), id == R.id.button_always);
        dismiss();
    }

    void startSelected(int which, boolean always) {
        if (isFinishing()) {
            return;
        }
        ResolveInfo ri = mAdapter.resolveInfoForPosition(which);
        Intent intent = mAdapter.intentForPosition(which);
        onIntentSelected(ri, intent, always);
        finish();
    }

    protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
        if (mAlwaysUseOption && mAdapter.mOrigResolveList != null) {
            // Build a reasonable intent filter, based on what matched.
            IntentFilter filter = new IntentFilter();

            if (intent.getAction() != null) {
                filter.addAction(intent.getAction());
            }
            Set<String> categories = intent.getCategories();
            if (categories != null) {
                for (String cat : categories) {
                    filter.addCategory(cat);
                }
            }
            filter.addCategory(Intent.CATEGORY_DEFAULT);

            int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
            Uri data = intent.getData();
            if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
                String mimeType = intent.resolveType(this);
                if (mimeType != null) {
                    try {
                        filter.addDataType(mimeType);
                    } catch (IntentFilter.MalformedMimeTypeException e) {
                        Log.w("ResolverActivity", e);
                        filter = null;
                    }
                }
            }
            if (data != null && data.getScheme() != null) {
                // We need the data specification if there was no type,
                // OR if the scheme is not one of our magical "file:"
                // or "content:" schemes (see IntentFilter for the reason).
                if (cat != IntentFilter.MATCH_CATEGORY_TYPE
                        || (!"file".equals(data.getScheme())
                                && !"content".equals(data.getScheme()))) {//注意这里排除了"file://", "content://"
                    filter.addDataScheme(data.getScheme());

                    // Look through the resolved filter to determine which part
                    // of it matched the original Intent.
                    Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
                    if (pIt != null) {
                        String ssp = data.getSchemeSpecificPart();
                        while (ssp != null && pIt.hasNext()) {
                            PatternMatcher p = pIt.next();
                            if (p.match(ssp)) {
                                filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
                                break;
                            }
                        }
                    }
                    Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
                    if (aIt != null) {
                        while (aIt.hasNext()) {
                            IntentFilter.AuthorityEntry a = aIt.next();
                            if (a.match(data) >= 0) {
                                int port = a.getPort();
                                filter.addDataAuthority(a.getHost(), port >= 0 ? Integer.toString(port) : null);
                                break;
                            }
                        }
                    }
                    pIt = ri.filter.pathsIterator();
                    if (pIt != null) {
                        String path = data.getPath();
                        while (path != null && pIt.hasNext()) {
                            PatternMatcher p = pIt.next();
                            if (p.match(path)) {
                                filter.addDataPath(p.getPath(), p.getType());
                                break;
                            }
                        }
                    }
                }
            }

            if (filter != null) {
                final int N = mAdapter.mOrigResolveList.size();
                ComponentName[] set = new ComponentName[N];
                int bestMatch = 0;
                for (int i=0; i<N; i++) {
                    ResolveInfo r = mAdapter.mOrigResolveList.get(i);
                    set[i] = new ComponentName(r.activityInfo.packageName, r.activityInfo.name);
                    if (r.match > bestMatch) bestMatch = r.match;
                }
                if (alwaysCheck) {
                    getPackageManager().addPreferredActivity(filter, bestMatch, set, intent.getComponent());//设置默认
                } else {
                    try {
                        AppGlobals.getPackageManager().setLastChosenActivity(intent,
                                intent.resolveTypeIfNeeded(getContentResolver()),
                                PackageManager.MATCH_DEFAULT_ONLY,
                                filter, bestMatch, intent.getComponent());
                    } catch (RemoteException re) {
                        Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
                    }
                }
            }
        }

        if (intent != null) {
            startActivity(intent);
        }
    }




当系统存在多个launcher时,若没有设置默认launcher,开机启动后会弹出提示框,罗列所有launcher,用户选择并设置了默认launcher后,按home键以及以后重启都会进入默认的launcher。

现在,我希望系统能直接就进入我设定的launcher而不是弹出框后选择然后设置


网上大部分的做法就是修改

1
packages/apps/Provision/src/com/android/DefaultActivity.java

1
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java


两个文件,给个相对比较好看一点的链接http://blog.csdn.net/z_guijin/article/details/8964890

我按照这个做不能达到预期的效果,


/添加内容

后期修改包名,发现开机自启动出现问题,然后弄了两天,终于差不多弄清楚了。果然,欠下的债迟早得还!

其实修改DefaultActivity.java就能够完成开机自启动,只是当时我的程序有问题,所以没有达到预期效果


当然下面修改ActivityManagerService.java也能完成开机自启动


这两者的区别在于
DefaultActivity.java只是在第一次启动时执行,如果修改了默认launcher后不可恢复

ActivityManagerService.java在每次启动时执行,每次都默认启动设定的launcher,当然,如果设定的launcher存在的话,设置其他的launcher为默认会无效,因为重新启动时setDefaultLauncher()会将当前默认launcher清除。只有在卸载了设定默认启动的launcher后才能设置其他launcher为默认启动.

//


修改多次搜索关键字,得到另一篇文章,大致看了下,感觉不会有效,但是已经绝望了就试了试,竟然解决了问题http://blog.csdn.net/jia4525036/article/details/18036765

这篇文章有借鉴之处,直接使用时会发现有些字段是上下文中没有的,故写下此文记录一下。


修改文件

1
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java

添加一个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
     private  void  setDefaultLauncher() {  
         // get default component   
         String packageName =  "com.coship.factorytest" ; //默认launcher包名
         String className =  "com.coship.factorytest.MainActivity" ; 默认launcher入口
          
         IPackageManager pm = ActivityThread.getPackageManager();
         
         //判断指定的launcher是否存在
         if (hasApkInstalled(packageName)) {
         
             Slog.i(TAG,  "defautl packageName = "  + packageName +  ", default className = "  + className); 
                       
             //清除当前默认launcher 
             ArrayList<IntentFilter> intentList =  new  ArrayList<IntentFilter>();  
             ArrayList<ComponentName> cnList =  new  ArrayList<ComponentName>();  
             mContext.getPackageManager().getPreferredActivities(intentList, cnList,  null );  
             IntentFilter dhIF =  null ;  
             for ( int  i =  0 ; i < cnList.size(); i++) {  
                 dhIF = intentList.get(i);  
                 if (dhIF.hasAction(Intent.ACTION_MAIN) && dhIF.hasCategory(Intent.CATEGORY_HOME)) {  
                     mContext.getPackageManager().clearPackagePreferredActivities(cnList.get(i).getPackageName());  
                 }  
             }  
                       
             //获取所有launcher activity 
             Intent intent =  new  Intent(Intent.ACTION_MAIN);  
             intent.addCategory(Intent.CATEGORY_HOME);  
             List<ResolveInfo> list =  new  ArrayList<ResolveInfo>();  
             try  {  
                 list = pm.queryIntentActivities(intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), PackageManager.MATCH_DEFAULT_ONLY);  
             } catch  (RemoteException e) {  
                 throw  new  RuntimeException( "Package manager has died" , e);  
             }   
             // get all components and the best match  
             IntentFilter filter =  new  IntentFilter();  
             filter.addAction(Intent.ACTION_MAIN);  
             filter.addCategory(Intent.CATEGORY_HOME);  
             filter.addCategory(Intent.CATEGORY_DEFAULT);  
             final  int  N = list.size();  
             Slog.d(TAG,  "N:::::hyhyhyhy:::: = "  + N);  
                     
             //设置默认launcher 
             ComponentName launcher =  new  ComponentName(packageName, className);  
 
             ComponentName[] set =  new  ComponentName[N];  
             int  defaultMatch =  0 ;  
             for  ( int  i =  0 ; i < N; i++) {  
                 ResolveInfo r = list.get(i);  
                 set[i] =  new  ComponentName(r.activityInfo.packageName, r.activityInfo.name);  
                 Slog.d(TAG,  "r.activityInfo.packageName:::::hyhyhyhy:::: = "  + r.activityInfo.packageName);
                 Slog.d(TAG,  "r.activityInfo.name:::::hyhyhyhy:::: = "  + r.activityInfo.name);
                 if (launcher.getClassName().equals(r.activityInfo.name)) {
                     defaultMatch = r.match;
                 }
             }  
                     
             try  {  
                 pm.addPreferredActivity(filter, defaultMatch, set, launcher);
             catch  (RemoteException e) {  
                 throw  new  RuntimeException( "com.coship.factorytest.MainActivity : Package manager has died" , e);  
             }   
             
             
         } //end if
         
     }  
 
     private  static  boolean  hasApkInstalled(String pkgname) {
 
         try  {
             mSelf.mContext.getPackageManager().getPackageInfo(pkgname, 0 );
         catch (Exception e) {
             Slog.d(TAG,  "PackageManager.NameNotFoundException: = "  + e.getMessage());
             return  false ;
         }
         return  true ;
     }

然后在ActivityManagerService类中的

1
boolean  startHomeActivityLocked()

方法第一行调用上面添加的

1
setDefaultLauncher()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
   boolean  startHomeActivityLocked() {
     
         if  (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                 && mTopAction ==  null ) {
             // We are running in factory test mode, but unable to find
             // the factory test app, so just sit around displaying the
             // error message and don't try to start anything.
             return  false ;
         }
 
///
         setDefaultLauncher();
///
         
         Intent intent =  new  Intent(
             mTopAction,
             mTopData !=  null  ? Uri.parse(mTopData) :  null );
         intent.setComponent(mTopComponent);
         if  (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
             intent.addCategory(Intent.CATEGORY_HOME);
         }
         ActivityInfo aInfo =
             intent.resolveActivityInfo(mContext.getPackageManager(),
                     STOCK_PM_FLAGS);
         if  (aInfo !=  null ) {
             intent.setComponent( new  ComponentName(
                     aInfo.applicationInfo.packageName, aInfo.name));
             // Don't do this if the home app is currently being
             // instrumented.
             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                     aInfo.applicationInfo.uid);
             if  (app ==  null  || app.instrumentationClass ==  null ) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mMainStack.startActivityLocked( null , intent,  null null 0 , aInfo,
                         null null 0 0 0 false false null );
             }
         }
         
         
         return  true ;
     }

添加后的方法全部内容如上,重新编译android,烧录,开机就能够自动进入自定义的launcher

可以通过系统设置取消该launcher的默认设置,取消之后按home键会弹出launcher选择提示框

1
frameworks\base\core\java\com\android\internal\app\ResolverActivity.java

ResolverActivity类就是选择打开方式的弹出框

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值