使用Intent Filter实现插件和扩展

   

到目前为止,你已经学会了如何显式地创建隐式Intent,但这只是故事的一半。Android允许后来的包为已有的应用程序提供新的功能,在运行时使用Intent Filter动态地填入菜单。

 

这为你的Activity提供了插件模型,使它们可以利用目前还未构想到的新应用程序组件的功能性,而不需要修改或重新编译你的工程。

 

Menu类的addIntentOptions方法允许你指定一个Intent,它描述了这个Menu要作用的数据。Android解析这个Intent并返回每个在Intent Filter中匹配特定的数据的指定动作。为每一个创建一个新的菜单项,用匹配的Intent Filter的标签来填入文本。

 

这个概念的优雅之处可以通过例子很好的解释清楚。话说你的应用程序显示的数据是地点的列表。跳到几年前的某一个时刻,菜单动作可能包括“查看”和“显示去的方向”,现在你创建了一个应用程序与汽车交互,允许你的电话来处理驾驶。感谢运行时的菜单生成,通过在新的Activity节点里包含一个新的Intent Filter(里面有一个DRIVE_CAR动作),Android会自动地在你的老应用程序里为这个动作添加一个新的菜单项。

 

当你创建了一个能在特定类型数据上执行动作的新组件时,运行时菜单填入机制让程序的功能具有了翻新的能力。许多Android本身的应用程序使用这个功能,让你可以在本地的Activity中增添额外的动作。

 

为应用程序提供匿名动作

 

为了让其它应用程序获得这些动作,通过在它们的manifest节点里添加intent-filter标签来发布它们。

 

Intent Filter描述了它能执行的动作以及可以执行的数据。后者在Intent解析过程中决定什么时候这个动作有效的期间使用。种类的标签必须是ALTERNATIVESELECTED_ALTERNATIVE之一或两者。菜单项使用的文本在android:label属性中指定。

 

下面的XML显示了使用Intent Filter来发布一个Activity有从轨道上秒杀月球的能力。

 

<activity android:name=”.NostromoController”>

<intent-filter android:label=”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>

 

Content Provider和用来运行这个例子的其它代码没有提供;接下来的章节里,你将会看到如何书写代码来让这个动作在其它的Activity的菜单中可用。

 

在你的Activity菜单中并入匿名动作

 

在运行时为你的菜单添加选项,你可以考虑在菜单对象上使用addIntentOptions方法,传入一个Intent,指定了你想提供的动作所需的数据。一般来说,它会被ActivityonCreateOptionsMenuonCreateContextMenu处理函数处理。

 

你创建的Intent将用于解析在Intent Filter中提供了能在你指定数据上执行动作的组件。Intent用于查找动作,所以不要指定一个;它只需要指定指定动作所需的数据。你也必须制定动作的种类为CATEGORY_ALTERNATIVECATEGORY_SELECTED_ALTERNATIVE

 

下面的框架代码显示了为菜单-动作解析创建一个Intent

 

Intent intent = new Intent();

intent.setData(MyProvider.CONTENT_URI);

intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

 

在你想要填入的菜单里传递这个IntentaddIntentOptions方法中,还包括任一选项标志,调用类的名称,菜单的组和菜单的ID值。你还可以指定一个Intent数据来创建附加的菜单项。

 

接下来的代码片段给出了如何动态填入Activity菜单的想法,它可能包含前一章节提到的“月球秒杀”的动作:

 

@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;

}

 

posted on 2009-07-31 16:05  xirihanlin  阅读(2365)  评论(2编辑  收藏  举报