源地址:http://developer.android.com/training/basics/intents/filters.html
前面两节都是单方面的讲了如果从你自己的APP启动别人的APP里面的Activity.但是如果你的APP如果能够执行某一个动作,那么对于其他的APP也许是很有用的,你的APP需要做好可以接收其他的APP 发过来的动作请求。比方说你开发一个社交APP,可以分享图片和信息给朋友,那么你的APP最好支持ACTION_SEND
intent,对你的应用很有利,这样用户就可以从其他的APP里面发起分享的动作,跳转到你的APP来分享用户要分享的信息。
要允许其他的APP启动你的activity,需要在manifest文件里面对应的<activity>
元素里面添加<intent-filter>
元素。
当你的APP被安装到设备的时候,系统会把<intent-filter>
里面的信息添加到一个目录里面,这个目录可以被所有安装的APP访问。当一个应用调用startActivity()
或者startActivityForResult(),里面的参数是一个模糊的intent的时候,系统会找出包含可以响应这个intent的activity,可能有多个。
添加一个
Intent Filter(Intent过滤器)
为了明确定义哪个intent你的activity可以处理,每一个你添加的intent过滤器都应该尽可能的明确指出可以处理的动作类型和接收的数据。
如果一个activity有一个intent过滤器满足下面的intent的标准,那么系统会发送一个指定的intent给这个activity.
Action(动作): 用string指定要要执行的action.例如通常使用的平台定义的这个值:ACTION_SEND
或者 ACTION_VIEW
.在你intent filter里面用<action>
元素来指定这一项,这个值必须是完整的字符串,不可以用系统的API里面的固定字串,看下面的例子。
Data(数据): 和intent相关联的数据的描述。这个属性使用<data>
元素指定。可以在这个里面指定多个属性,你可以只指定一个MIME类型,URI前缀或者RUI完整的方案,或者是他们几个的组合以及其他的可以表示这个activity接收的数据类型的值。
注意:如果不需要处理Uri的数据(比方说你的activity需要处理的数据为extra的数据),你仅仅需要指定android:mimeType属性来指定你的activity要处理的数据类型,比方说text/plain
或者 image/jpeg。
Category(类别):提供了额外的显示你的activity要处理的intent的方法,一般和用户的手势或者用户操作的起始位置有关系。有好几种系统支持的属性,但是几乎都不到。所有模糊的intent都会被默认的CATEGORY_DEFAULT属性。可以在过滤器里面用
<category>
指定。
在你的intent filter里面,你可以声明你的activity接收的intent的条件,可以在
<intent-filter>
用对应的XML标签来声明这些条件。
下面的声明是一个activity当遇到数据类型为text 或者 an image,处理ACTION_SEND的动作:
<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>
, and <data>
,这样只是会让我们的activity可以接收更多类型的intent.
任何两对动作和数据在行为上都是相互独立的,所在声明的时候,必须分开声明,为每一对动作和数据单独作为一个intent filter.
比方说要的你activity对ACTION_SEND
and ACTION_SENDTO动作都都处理数据:text 和 images,那么需要使用
send
或者 sendto
Uri方案来 定义2个分开的intent fileter。因为ACTION_SENDTO 动作的intent必须使用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,你必须在intent filter里面包含CATEGORY_DEFAULT属性。方法
startActivity()
and startActivityForResult()会认为所有的intent都包含CATEGORY_DEFAULT属性。如果不声明这个属性,那么没有intent会被发送到你的activity.
想要了解更多的利用
ACTION_SEND动作来进行分享的目的,阅读:Receiving Content from Other Apps.
在你的Activity里面处理接收到的Intent
为了搞清楚你的activity接收到的intent里面是哪种动作,首先要读取用来启动你的activity的那个intent.
当你的activity启动的时候,调用getIntent()得到启动你的activity的那个intent.可以在activity生命周期的任何一个地方来获取这个intent,一般最好在生命周期早期的回调函数里面处理它,如
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();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
}
返回结果
如果你想给唤起你的那个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,之前的activity会收到一个返回码为”cancle”的结果。
如果你仅仅是想知道某些操作的结果,那么可以把返回码设置为任意大于0的是整数。那就是仅仅用返回码来传递一个整数,我们不需要为这个结果在设置intent,可以调用
setResult()的时候仅仅给一个整数作为参数就可以了。如下:
setResult(RESULT_COLOR_RED);
finish();
在这种情况下,可能返回码只有那么几种,所以这返回码可以在本地预先定义好。这样做的好处是,如果是在同一个APP里面,一个activity接收另外一个activity的返回结果,那么接收结果的这个activity就可以利用定义为公共变量的返回码来判断返回的结果的返回码是哪个。
注意:不需要去判断你的activity是被startActivity()
和 startActivityForResult()哪个方法启动的。如果希望启动你那个activity希望有返回结果,简单的用
setResult()设置就好。如果前面的activity使用了
startActivityForResult()方法来启动你的activity,希望得到一个返回结果。那么系统就会把setResult设置的intent返回给它,否则,如果不需要一个返回结果,是用
startActivity()
来启动的,这个返回结果就会默认被忽略掉。