标签:
我们经常会通过一个Intent来启动一个Activity,但是如果有多个Application注册了相同的Action,这时会怎么样呢? Android 为我们提供了选择对话框即把所有的接收到此Action的Application对列表的形式放到对话框中,让用户选择打开哪一个Application。同样的也可以设置默认打开的Application。像Windows中的默认打开方式。
Android系统对于每个Activity的注册信息是如何管理的?
选择应用的对话框是如何打开的?
如何知道哪些Application的Activity注册了相同的Action?
如何知道,我们是选择了哪个Application的哪个Activity,后续又是如何处理的?
。。。。。
这些暂不讨论,后续完善!这里只讨论下,如何把某个Application设置默认启动的:
我们知道实际上在选把应用的对话框上有一个设为默认启动的选项,选中后,我们再选择某个Application,后续就会直接启动默认选中的Application代码是是怎么实现的呢:
frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
1 protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) { 2 if (alwaysCheck) { 3 // Build a reasonable intent filter, based on what matched. 4 IntentFilter filter = new IntentFilter(); 5 6 if (intent.getAction() != null) { 7 filter.addAction(intent.getAction()); 8 } 9 Set<String> categories = intent.getCategories(); 10 if (categories != null) { 11 for (String cat : categories) { 12 filter.addCategory(cat); 13 } 14 } 15 filter.addCategory(Intent.CATEGORY_DEFAULT); 16 17 int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK; 18 Uri data = intent.getData(); 19 if (cat == IntentFilter.MATCH_CATEGORY_TYPE) { 20 String mimeType = intent.resolveType(this); 21 if (mimeType != null) { 22 try { 23 filter.addDataType(mimeType); 24 } catch (IntentFilter.MalformedMimeTypeException e) { 25 Log.w("ResolverActivity", e); 26 filter = null; 27 } 28 } 29 } 30 if (data != null && data.getScheme() != null) { 31 // We need the data specification if there was no type, 32 // OR if the scheme is not one of our magical "file:" 33 // or "content:" schemes (see IntentFilter for the reason). 34 if (cat != IntentFilter.MATCH_CATEGORY_TYPE 35 || (!"file".equals(data.getScheme()) 36 && !"content".equals(data.getScheme()))) { 37 filter.addDataScheme(data.getScheme()); 38 39 // Look through the resolved filter to determine which part 40 // of it matched the original Intent. 41 Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator(); 42 if (aIt != null) { 43 while (aIt.hasNext()) { 44 IntentFilter.AuthorityEntry a = aIt.next(); 45 if (a.match(data) >= 0) { 46 int port = a.getPort(); 47 filter.addDataAuthority(a.getHost(), 48 port >= 0 ? Integer.toString(port) : null); 49 break; 50 } 51 } 52 } 53 Iterator<PatternMatcher> pIt = ri.filter.pathsIterator(); 54 if (pIt != null) { 55 String path = data.getPath(); 56 while (path != null && pIt.hasNext()) { 57 PatternMatcher p = pIt.next(); 58 if (p.match(path)) { 59 filter.addDataPath(p.getPath(), p.getType()); 60 break; 61 } 62 } 63 } 64 } 65 } 66 67 if (filter != null) { 68 final int N = mAdapter.mList.size(); 69 ComponentName[] set = new ComponentName[N]; 70 int bestMatch = 0; 71 for (int i=0; i<N; i++) { 72 ResolveInfo r = mAdapter.mList.get(i).ri; 73 set[i] = new ComponentName(r.activityInfo.packageName, 74 r.activityInfo.name); 75 if (r.match > bestMatch) bestMatch = r.match; 76 } 77 getPackageManager().addPreferredActivity(filter, bestMatch, set, 78 intent.getComponent()); 79 } 80 } 81 82 if (intent != null) { 83 startActivity(intent); 84 } 85 }
如上代码即为选中某个Application时的处理,最重要的就是这句getPackageManager().addPreferredActivity(filter, bestMatch, set,intent.getComponent());设置默认的启动项。
下面为自定义的用代码来自动的设置默认的启动项,不用手动的点击设置默认项那么麻烦:
1 private void setDefaultLauncher() { 2 3 PackageManager pm = null; 4 IntentFilter intentFilter; 5 6 //check permission 7 if (PermissionUtils.checkPermission(mContext, 8 mContext.getPackageName(), 9 "android.permission.SET_PREFERRED_APPLICATIONS")) { 10 pm = getPackageManager(); 11 12 ArrayList<IntentFilter> intentList = new ArrayList<IntentFilter>(); 13 ArrayList<ComponentName> cnList = new ArrayList<ComponentName>(); 14 int number= pm.getPreferredActivities(intentList, cnList, null); 15 LogUtils.d("debug", "the number of distinct IntentFilter records = " 16 + number); 17 18 //clean default 19 for (int i = 0; i < cnList.size(); i++) { 20 intentFilter = intentList.get(i); 21 if (intentFilter.hasAction(Intent.ACTION_MAIN) 22 && intentFilter.hasCategory(Intent.CATEGORY_HOME)) { 23 pm.clearPackagePreferredActivities(cnList.get(i) 24 .getPackageName()); 25 } 26 } 27 28 //application list with same action 29 Intent intent = new Intent(Intent.ACTION_MAIN); 30 intent.addCategory(Intent.CATEGORY_HOME); 31 List<ResolveInfo> list = new ArrayList<ResolveInfo>(); 32 33 list = pm.queryIntentActivities(intent, 34 PackageManager.MATCH_DEFAULT_ONLY); 35 36 IntentFilter filter = new IntentFilter(); 37 filter.addAction(Intent.ACTION_MAIN); 38 filter.addCategory(Intent.CATEGORY_HOME); 39 filter.addCategory(Intent.CATEGORY_DEFAULT); 40 final int N = list.size(); 41 ComponentName[] set = new ComponentName[N]; 42 int bestMatch = 0; 43 //get best match 44 for (int i = 0; i < N; i++) { 45 ResolveInfo r = list.get(i); 46 set[i] = new ComponentName(r.activityInfo.packageName, 47 r.activityInfo.name); 48 if (r.match > bestMatch) 49 bestMatch = r.match; 50 } 51 52 //add component 53 ComponentName launcher = new ComponentName( 54 "com.test.switch", 55 "com.test.switch.TestActivity"); 56 57 pm.addPreferredActivity(filter, bestMatch, set, launcher); 58 } else { 59 LogUtils.d("debug", "no permission"); 60 } 61 }
标签:
原文地址:http://www.cnblogs.com/pillowzhou/p/4671944.html