android学习之IntentFilter

Intent-Filter 可以理解为intent的过滤器。

可在mainfest中主要包含以下成分:

action:每个intent-filter至少要一个action标签。

category:

1.ALTERNATIVE

2.SELECTED_ALTERNATIVE

3.BROWSABLE

4.DEFAULT 默认的类别。//隐式启动activity时必须包含。(intent默认包含DEFAULT)

5.HOME

6.LAUNCHER

data:

1.android:host

2.android:mimetype

3.android:path(如/aa/bb)

4.android:port(端口)

5.android:scheme(比如content,http,mailto,tel) //uri的协议部分

这些属性,能否让你想到uri呢?

隐式启动时,安卓是如何应对这些Intent的过滤器呢?

答:

1.把所有已安装的app中可用的过滤器放到一个list中。

2.遍历list,过滤器与当前Intent不匹配的将从这个list中移除。

如何匹配?

1.intent-filter可以包含多个action,category,data,action是必不可少的,category是可选择的(启动activity时,必须包含个DEFAULT),data可选择。

2.intent中包含的category(因为可以addCategory,可能有多个),intent-filter必须包含所有intent所指定的(多了可以,少了不可以),否则将不匹配,这个过滤器将被移除。反过来说,intent-filter所包含的category,一个或者多个,intent只要符合一个即可,是或的关系,成立一个即可,data也存在或的关系。

3.data呢? 比如intent的uri包含的scheme,host,port,那么Intent-filter的data标签最多可以包含对应的这3个属性值(且包含的值必须与Intent中uri的成分一致),多了不匹配,少了某个属性或是没有data标签都可以匹配。反过来说,intent-filter指定了某一个data scheme,host等,intent必须包含所有的(多了可以,少了不可以)。

4.只要一个data标签符合就可通过检验,即便过滤器中有多个data标签,前面提到过,是或的关系。

 

当startActivity时,传过去的intent我该如何获取呢?

答:Intent intent = getIntent();  String action  = intent.getAction(); Uri data = intent.getData();

 

当Activity如有类似不会重新创建activity的启动模式,当第2次调用startActivity时,才会触发onNewIntent

@Override 
public void onNewIntent(Intent newIntent) { 
   // TODO React to the new Intent 
   super.onNewIntent(newIntent); 
}

 

还记得activity的启动模式否? 某些模式activity不会被重新创建,所以你不太可能在onCreate里接收到连续发来的Intent(比如Notification触发的),这个时候onNewIntent的作用就来了。

 

启动intent,交给下一个最佳匹配者处理比如我是第一个处理的,你再startNext…,就不会给我处理了,而是下一个。)

startNextMatchingActivity(intent)

 

App支持匿名Actions

首先,intent-filter中的category必须有ALTERNATIVE或者SELECTED_ALTERNATIVE,或者是两个都有。android:label必须清楚描述action。(label通常比较重要,比如后面提到的合并)

在mainfest中类似与:

         <activity android:name=”.NostromoController”> 
            <intent-filter 
              android:label=”@string/Nuke_From_Orbit”> 
              <action android:name=”com.pad.nostromo.NUKE_FROM_ORBIT”/> 
              <data android:mimeType=”vnd.moonbase.cursor.item/*”/> 
              <category android:name=”android.intent.category.ALTERNATIVE”/> 
              <category 
                 android:name=”android.intent.category.SELECTED_ALTERNATIVE” 
              /> 
            </intent-filter> 
         </activity> 

 

JavaCode:

PackageManager packageManager = getPackageManager();

//创建intent,用来决定应该什么样的actions出现在菜单中。
Intent intent = new Intent(); //注意到没有指定action,所谓的匿名 
intent.setData(MoonBaseProvider.CONTENT_URI); 
intent.addCategory(Intent.CATEGORY_SELECTED_ALTERNATIVE);

//指定标识,用于返回只有DEFAULT类别的过滤器。
int flags = PackageManager.MATCH_DEFAULT_ONLY;

// 生成List 
List<ResolveInfo> actions; 
actions = packageManager.queryIntentActivities(intent, flags);

//取出list中每个过滤器的标签
ArrayList<String> labels = new ArrayList<String>(); 
Resources r = getResources(); 
for (ResolveInfo action : actions )  
labels.add(r.getString(action.labelRes));

 

合并匿名Actions作为菜单条目

比较常见的方式就是去合并来自第3方的APP的actions,然后将它们放在菜单或者action bars上。

Java Code:

 @Override 
public boolean onCreateOptionsMenu(Menu menu) { 
   super.onCreateOptionsMenu(menu);

   // Create the intent used to resolve which actions 
   // should appear in the menu. 
   Intent intent = new Intent(); 
   intent.setData(MoonBaseProvider.CONTENT_URI); 
   intent.addCategory(Intent.CATEGORY_SELECTED_ALTERNATIVE);

   // Normal menu options to let you set a group and ID 
   // values for the menu items you’re adding. 
   int menuGroup = 0; 
   int menuItemId = 0; 
   int menuItemOrder = Menu.NONE;

   // Provide the name of the component that’s calling 
   // the action -- generally the current Activity. 
   ComponentName caller = getComponentName();

   // Define intents that should be added first. 
   Intent[] specificIntents = null; 
   // The menu items created from the previous Intents 
   // will populate this array. 
   MenuItem[] outSpecificItems = null;

   // Set any optional flags. 
   int flags = Menu.FLAG_APPEND_TO_GROUP;

   // Populate the menu 
   menu.addIntentOptions(menuGroup, 
                              menuItemId, 
                              menuItemOrder, 
                              caller, 
                              specificIntents, 
                              intent, 
                              flags, 
                              outSpecificItems);

   return true; 

 }

 

 相当于你将选择出来的目标放在了menu中,

那么menu是如何显示这些action呢?

答:是以intent-filter的label为每个菜单的名字,但好玩的是,当你点击菜单项,它就可以帮你跳转到指定的activity。

你可能感兴趣的:(android,intent-filter)