设置默认Browser

  电信A库要求android系统中有多个Browser时,开机自动设置一个默认浏览器,而不用弹出选择框让用户手动选择。

  监听开机广播Intent.ACTION_BOOT_COMPLETED, 用PackageManager调用addPreferredActivity来设置默认Browser。因为要有系统权限才能设置成功,所以在Package/apps/Settings模块中添加代码实现。(系统通过校验发起调用PackageManager.addPreferredActivity程序的Uid来判断是否有权限)

 1 public class BootCompletedReceiver extends BroadcastReceiver {
 2 
 3     private final static String PKG_NAME = "com.android.browser";
 4     private final static String CLASS_NAME = "com.android.browser.BrowserActivity";
 5 
 6     private final static String[] SCHEME = new String[] { "http", "https", "about", "javascript", };
 7     
 8     @Override
 9     public void onReceive(Context c, Intent paramIntent) {
10         try {
11             Log.d("antoon", paramIntent.getAction());
12             setDefaultBrowser(c);
13         } catch (Exception e) {
14             e.printStackTrace();
15         }
16     }
17 
18     private void setDefaultBrowser(Context c) {
19         
20         long start = System.currentTimeMillis();
21         
22         Intent intent = new Intent(Intent.ACTION_VIEW);
23         intent.setData(Uri.parse("http://"));//这里如果配置 “file://” pm.queryIntentActivities得到的list为空,不知为何
24         
25         final int flags = PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_RESOLVED_FILTER;
26 
27         PackageManager pm = c.getPackageManager();
28         List<ResolveInfo> list = pm.queryIntentActivities(intent, flags);
29 
30         final int N = list == null ? 0 : list.size();
31         if (N == 0)
32             return;
33 
34         int bestmatch = 0;
35         int uid = -1;
36         ComponentName matchComponentName = null;
37         ComponentName[] set = new ComponentName[N];
38 
39         ComponentName defaultComponentName = new ComponentName(PKG_NAME, CLASS_NAME);
40         for (int i = 0; i < N; i++) {
41             ResolveInfo r = list.get(i);
42             ComponentName cp = new ComponentName(r.activityInfo.packageName, r.activityInfo.name);
43             set[i] = cp;
44             if (cp.equals(defaultComponentName)) {
45                 bestmatch = r.match;
46                 matchComponentName = cp;
47                 uid = r.activityInfo.applicationInfo.uid;
48             }
49             Log.d("antoon", i + " -- " + cp);
50         }
51 
52         if (matchComponentName == null) {
53             Log.d("antoon", "matchComponentName is null");
54             matchComponentName = set[0];
55             bestmatch = list.get(0).match;
56         }
57 
58         Log.d("antoon", "bestmatch = " + bestmatch + "   matchComponentName = "
59                 + matchComponentName);
60 
61        // List<IntentFilter> filterList = filterList();
62         //for (IntentFilter filter : filterList) {
63            // pm.addPreferredActivity(filter, bestmatch, set, matchComponentName);//用下面的方法也可以,系统权限的校验就是根据CallingUserId来判断
64 //            pm.addPreferredActivity(filter, bestmatch, set, matchComponentName, android.os.UserHandle.getCallingUserId());
65         //}
       pm.addPreferredActivity(getFilterViewHttp(), bestmatch, set, matchComponentName, android.os.UserHandle.getCallingUserId());
66 Log.d("antoon", "used time :" + (System.currentTimeMillis() - start)+"ms"); 67 } 68 69
      /*没必要针对每个scheme创建filter,在一个filter中加入所有scheme就可以,与Browser中AndroidManifest.xml中的配置对应。
      public List<IntentFilter> filterList() { 70   ArrayList<IntentFilter> list = new ArrayList<IntentFilter>(); 71   for (String sche : SCHEME) { 72   IntentFilter filter = new IntentFilter(); 73   filter.addAction(Intent.ACTION_VIEW); 74   filter.addCategory(Intent.CATEGORY_BROWSABLE); 75   filter.addCategory(Intent.CATEGORY_DEFAULT); 76   filter.addDataScheme(sche); 77   list.add(filter); 78   } 79   return list; 80   }
      */
    
     public IntentFilter getFilterViewHttp() {
            
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_VIEW);
            filter.addCategory(Intent.CATEGORY_BROWSABLE);
            filter.addCategory(Intent.CATEGORY_DEFAULT);
            filter.addDataScheme("http");           
            
            return filter;
        }
81 
82 }
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <receiver android:name=".BootCompletedReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

看看系统Browser的配置

    <activity
            android:name="BrowserActivity"
            android:alwaysRetainTaskState="true"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
            android:label="@string/application_name"
            android:launchMode="singleTask"
            android:theme="@style/BrowserTheme"
            android:windowSoftInputMode="adjustResize" >
            <intent-filter>
                <action android:name="android.speech.action.VOICE_SEARCH_RESULTS" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <!--
                 For these schemes were not particular MIME type has been
                 supplied, we are a good candidate.
            -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="about" />
                <data android:scheme="javascript" />
            </intent-filter>
            <!--
                  For these schemes where any of these particular MIME types
                  have been supplied, we are a good candidate.
            -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="inline" />
                <data android:mimeType="text/html" />
                <data android:mimeType="text/plain" />
                <data android:mimeType="application/xhtml+xml" />
                <data android:mimeType="application/vnd.wap.xhtml+xml" />
            </intent-filter>
            <!-- For viewing saved web archives. -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="file" />
                <data android:mimeType="application/x-webarchive-xml" />
            </intent-filter>
            <!-- Accept inbound NFC URLs at a low priority -->
            <intent-filter android:priority="-101" >
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
            <!-- We are also the main entry point of the browser. -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.APP_BROWSER" />
            </intent-filter>
            <!--
            The maps app is a much better experience, so it's not
                 worth having this at all... especially for a demo!
            <intent-filter android:label="Map In Browser">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/postal-address" />
            </intent-filter>
            -->
            <intent-filter>
                <action android:name="android.intent.action.WEB_SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.WEB_SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="" />
                <data android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

参考:http://www.apkbus.com/forum.php?mod=viewthread&tid=225694&page=1#pid3159981

原文地址:https://www.cnblogs.com/antoon/p/4430032.html