前面两个课程侧重于讲解怎样从您的APP启动另一个APP的Activity。但是,如果您的APP有供其它APP调用的功能,则应该准备好响应其他APP的调用请求。例如,如果您的APP有在朋友圈分享信息的功能,则最好支持ACTION_SEND Intent,以便用户可以从另一个APP启动您的APP来完成“分享”操作。
要允许其他APP启动您的Activity,您需要在manifest文件中为相应的元素添加一个元素。
当您的应用程序安装在设备上时,系统会识别您的Intent Filter,并将信息添加到一个所有已安装APP都支持的内部目录。当APP使用隐式Intent调用startActivity()或startActivityForResult()时,系统会发现哪些Activity可以这个响应Intent。
添加Intent Filter
为了正确地定义您的Activity可以处理哪些Intent,您添加的每个Intent Filter应尽可能具体到Activity接受的Action和Data类型。如果Activity的Intent Filter符合Intent对象的以下条件,则系统就向此Activity发送给定的Intent:
Action:一个命名执行操作的字符串。通常是Android平台定义的值,如ACTION_SEND或ACTION_VIEW。
在Intent Filter中使用元素指定。您在此元素中指定的值必须是Action的完整字符串名称,而不是API常量(请参见下面的示例)。
Data:与Intent相关联的数据。
在Intent Filter中使用元素指定。在此元素中使用一个或多个属性,可以指定MIME类型,或只指定URI前缀,或只指定URI scheme,或者指定其它能指示接受数据类型的属性,或者这些属性的组合。
注意:如果您不需要声明Data Uri的详细信息(例如当您的Activity处理其他类型的“extra”数据而不是URI时),则应仅指定android:mimeType属性来声明您的Activity处理的数据类型,例如text / plain或image / jpeg。
Category:提供一种额外的方法来识别处理Intent的Activity,通常与用户手势或其开始的位置相关。系统支持几种不同的categories,但大多数都是很少使用的。但是,默认情况下,所有隐式Intent都使用CATEGORY_DEFAULT定义。
在Intent Filter中使用元素指定。
在Intent Filter中,您可以通过在元素中定义每个标准,以声明您的Activity接受哪些条件。
如下例子,一个Activity有一个Intent Filter,只处理Action为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仅指定一个Action和一个数据类型,但可以在每个中声明,和元素的多个实例。
如果任何两对Action和Data相互排斥,则应该创建单独的Intent Filter,以指定当与哪些数据类型配对时可以接受哪些Action。
例如,假设您的Activity处理Action为ACTION_SEND和ACTION_SENDTO的文本和图像。在这种情况下,您必须为两个Action定义两个单独的Intent Filter,因为ACTION_SENDTO必须使用data 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()和startActivityForResult()默认所有Intent声明了CATEGORY_DEFAULT类别。如果不在Intent Filter中声明它,则您的APP不会接收到隐式Intent。
有关社交分享功能发送和接收ACTION_SEND的更多信息,请参阅Receiving Simple Data from Other Apps。
处理Activity中的Intent
通过读取启动Activity的Intent,可以获得Intent携带的Action,Activity就能做相应的处理。在Activity启动时,调用getIntent()来获取启动该Activity的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();
// 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()来指定result code和result 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 code来指定返回结果,常用的有RESULT_OK和RESULT_CANCELED,且您可以根据需要向Intent提供Extra数据。
注意:默认情况下,结果设置为RESULT_CANCELED。因此,如果用户在完成操作之前(并且在设置结果之前)按下back键,则原始Activity将收到RESULT_CANCELED的结果。
如果您只需返回一个用于区分返回结果的整数,则可以将result code设置为高于0的任何整数。如果使用result code来传递一个整数,并且不需要包含Intent,那么可以调用setResult()并只传递一个result code。例如:
setResult(RESULT_COLOR_RED);
finish();
在这种情况下,只有少数可能的结果,因此result code是自定义的整数(大于0)。当您将结果返回到您自己的应用程序中的一个Activity时,接收结果的Activity可以引用公共常量来确定result code的值。
注意:无需检查您的Activity是以startActivity()还是startActivityForResult()启动的。如果启动您的Activity的Intent希望获取到返回的结果,只需调用setResult()。如果原始Activity调用了startActivityForResult()启动了目标Activity,那么系统将setResult()中的结果传递给原始Activity; 否则,结果将被忽略。