前面两课说的是:从你的程序启动其他程序的activity。但是如果你的程序可以实现某些功能,这些功能能够被其他程序使用,那么你的程序需要准备好响应其他程序的请求。例如,如果你做了一个可以分享信息和照片给朋友的社交程序,你最好让你的程序支持ACTION_SEND意图,以便用户可以在其他程序启动一个“分享”功能,并且运行你的程序去执行这个功能。
为了合理定义你的activity能够处理的intent,每个添加的过滤器必须尽可能详细的指明功能类型和activity支持的数据。
为了决定在activity中执行什么动作,你需要读取intent。
如果你想返回一个结果给调用你的activity,调用setResult()去指定结果代码和结果Intent。当你的操作完成,用户需要返回到原来的activity,你需要调用finish()去关闭你的activity。例如:
要让其他程序可以运行你的activity,你需要在相应的<activity>元素中添加一个<intent-filter>元素。
当你的程序安装到设备中时,系统会识别你的intent过滤器,并把这些信息添加到一个内部intent支持目录,这个目录包含所有安装好的程序所支持的intent。当程序调用startActivity()或者startActivityForResult(),并使用隐式intent时,系统会查找能够响应这个intent的activity。
添加一个Intent过滤器
为了合理定义你的activity能够处理的intent,每个添加的过滤器必须尽可能详细的指明功能类型和activity支持的数据。
如果activity包含的intent过滤器符合下面所有的Intent对象的条件,系统会发送一个给定的intent给activity:
Action
Data动作执行的字符串名称,通常使用一个平台指定值,如ACTION_SEND或者ACTION_VIEW。
使用intent过滤器的<action>元素指定。值必须是完整的动作名称,而不仅仅是API常数。
Category和intent相关联的数据描述。
使用<data>元素指定。这个元素可以使用一个或者多个属性,你可以指定只是MIME type,只是URI prefix,只是URI scheme,或者一个他们的组合体和其他可以接受的数据类型。
提示:如果你不详细的声明数据Uri(例如activity不是处理URI,而是其他附加数据),你应该仅指明一个android:mimeType属性去声明你的activity可以处理的数据类型,比如text/plain或者image/jpeg。
在你的intent过滤器中,你可以在<intent-filter>内部使用XML声明你的activity可以接受的条件。提供一个额外的方式去描述一个activity可以处理的intent,通常是关于用户开始的手势或者位置。这里有很多系统支持的分类,但是大部分不常用。所有隐式的intent都是默认定义了CATEGORY_DEFAULT分类。
使用<category>元素指定。
例如,这里有一个intent过滤器,它能处理ACTION_SEND Intent,数据必须是文本或者图像:
<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>是允许的。
如果两对动作和数据是相互独立的,你应该创建两个独立的intent过滤器去指定哪个动作接收哪个数据类型。
例如,假如你的activity使用ACTION_SEND和ACTION_SENDTO处理文本和图像。这种情况下,你必须定义两个独立的intent过滤器,因为ACTION_SENDTO intent必须使用Uri数据去指定收件人的地址,使用send或者sendto执行URI方案。例如:
<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。
更多关于发送和接收ACTION_SEND意图执行分享动作的信息,可以查看
Receiving Content from Other Apps。
在你的Activity中处理Intent
为了决定在activity中执行什么动作,你需要读取intent。
当你启动activity时,调用getIntent()去接收Intent。你可以在activity生命周期的任何时候调用,但是通常是在onCreate()或者onStart()中。
例如:
@Override protected 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 ... } }
返回一个结果
如果你想返回一个结果给调用你的activity,调用setResult()去指定结果代码和结果Intent。当你的操作完成,用户需要返回到原来的activity,你需要调用finish()去关闭你的activity。例如:
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"); setResult(Activity.RESULT_OK, result); finish();
你必须指定一个结果代码,通常是RESULT_OK或者RESULT_CANCELED。需要的话还可以附加数据到intent中。
提示:RESULT_CANCELED是默认的,如果用户在完成动作前,或者是设置结果前按返回按钮,那么原来的activity会接收到“canceled”结果。
如果你只是需要返回一个整形去指定多个操作中的一个,你可以设置结果代码为任何大于0的数。如果是使用结果代码发送一个数,你不需要包含Intent,你可以调用setResult()接收一个唯一的结果代码,例如:
setResult(RESULT_COLOR_RED); finish();
这种情况下,可能只有少数可能的结果,所有结果代码是一个本地定义的整数。在自己的程序中可以运行良好,因为这个结果代码可以被定义成公共的常量。
提示:不用判断你的activity是通过startActivity()还是startActivityForResult()启动的。只要调用setResult()就可以返回一个结果。如果原来的activity是通过startActivityForResult()调用的,系统就会发送你提供给setResult()的结果。startActivity()调用的话,结果会被忽略。