Android Training - 和其他程序交互(3) - 允许其他程序启动你的activity
前面两课说的是:从你的程序启动其他程序的activity。但是如果你的程序可以实现某些功能,这些功能能够被其他程序使用,那么你的程序需要准备好响应其他程序的请求。例如,如果你做了一个可以分享信息和照片给朋友的社交程序,你最好让你的程序支持ACTION_SEND意图,以便用户可以在其他程序启动一个“分享”功能,并且运行你的程序去执行这个功能。
要让其他程序可以运行你的activity,你需要在相应的<activity>元素中添加一个<intent-filter>元素。
当你的程序安装到设备中时,系统会识别你的intent过滤器,并把这些信息添加到一个内部intent支持目录,这个目录包含所有安装好的程序所支持的intent。当程序调用startActivity()或者startActivityForResult(),并使用隐式intent时,系统会查找能够响应这个intent的activity。
添加一个Intent过滤器为了合理定义你的activity能够处理的intent,每个添加的过滤器必须尽可能详细的指明功能类型和activity支持的数据。
如果activity包含的intent过滤器符合下面所有的Intent对象的条件,系统会发送一个给定的intent给activity:
Action
动作执行的字符串名称,通常使用一个平台指定值,如ACTION_SEND或者ACTION_VIEW。Data
使用intent过滤器的<action>元素指定。值必须是完整的动作名称,而不仅仅是API常数。
和intent相关联的数据描述。Category
使用<data>元素指定。这个元素可以使用一个或者多个属性,你可以指定只是MIME type,只是URI prefix,只是URI scheme,或者一个他们的组合体和其他可以接受的数据类型。
提示:如果你不详细的声明数据Uri(例如activity不是处理URI,而是其他附加数据),你应该仅指明一个android:mimeType属性去声明你的activity可以处理的数据类型,比如text/plain或者image/jpeg。
提供一个额外的方式去描述一个activity可以处理的intent,通常是关于用户开始的手势或者位置。这里有很多系统支持的分类,但是大部分不常用。所有隐式的intent都是默认定义了CATEGORY_DEFAULT分类。在你的intent过滤器中,你可以在<intent-filter>内部使用XML声明你的activity可以接受的条件。
使用<category>元素指定。
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter></activity>每个intent只能指定一个动作和一个数据类型,但是在<intent-filter>中声明多个<action>,<category>, <data>是允许的。
<activity android:name="ShareActivity"> <!-- filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter></activity>提示:为了接收隐式的intent,你必须包括CATEGORY_DEFAULT分类在intent过滤器中。startActivty()和startActivityForResult()处理所有包含了CATEGORY_DEFAULT分类的intent。如果不声明,那么隐式的intent不会匹配你的activity。
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // 基于intent类决定做什么 if (intent.getType().indexOf("image/") != -1) { // 使用图片类型处理intent ... } else if (intent.getType().equals("text/plain")) { // 使用文本类型处理intent ... }}
// Create intent to deliver some kind of result dataIntent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");setResult(Activity.RESULT_OK, result);finish();你必须指定一个结果代码,通常是RESULT_OK或者RESULT_CANCELED。需要的话还可以附加数据到intent中。
setResult(RESULT_COLOR_RED);finish();这种情况下,可能只有少数可能的结果,所有结果代码是一个本地定义的整数。在自己的程序中可以运行良好,因为这个结果代码可以被定义成公共的常量。