zoukankan      html  css  js  c++  java
  • 应用启动选择

    我们经常会通过一个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     }
  • 相关阅读:
    C#中StringBuilder类的使用总结
    java Socket长链接与消息推送源码与演示
    oracle merge into 小例
    webrtc 关闭摄像头
    WebRTC MediaRecorder API
    简单的菜单三
    简单的菜单二
    简单的菜单 一
    文件断点续传实现 ( 2-- C# 客户端)
    文件断点续传实现 (1 -- java实现)
  • 原文地址:https://www.cnblogs.com/pillowzhou/p/4671944.html
Copyright © 2011-2022 走看看