(六)Interacting with Other Apps与其他应用进行交互

本文首次发表于依鹏csdn博客,转载注明出处:http://blog.csdn.net/m0_37240709/article/details/77825870


Interacting with Other Apps与其他应用进行交互


An Android app typically has several activities. Each activity displays a user interface that allows the user to perform a specific task (such as view a map or take a photo). To take the user from one activity to another, your app must use an Intent to define your app's "intent" to do something. When you pass an Intent to the system with a method such as startActivity(), the system uses the Intent to identify and start the appropriate app component. Using intents even allows your app to start an activity that is contained in a separate app.
Android应用程序通常有几个活动。每个活动都显示一个用户界面,允许用户执行特定的任务(例如查看地图或拍照)。为了让用户从一个活动到另一个活动,你的应用必须使用一个意图来定义你的应用的“意图”来做某件事。当您使用诸如startActivity()这样的方法传递给系统的意图时,系统会使用意图来识别并启动适当的应用程序组件。使用意图甚至可以让你的应用启动一个包含在单独应用中的活动。
An Intent can be explicit in order to start a specific component (a specific Activity instance) or implicit in order to start any component that can handle the intended action (such as "capture a photo").
意图可以是显式的启动一个特定的组件(一个特定的活动实例),也可以隐式启动任何能够处理预期操作的组件(例如“捕获照片”)。
This class shows you how to use an Intent to perform some basic interactions with other apps, such as start another app, receive a result from that app, and make your app able to respond to intents from other apps.
这个课程向你展示了如何使用意图与其他应用进行一些基本的交互,比如启动另一个应用,接收来自该应用的结果,让你的应用能够响应来自其他应用的意图。

1、Sending the User to Another App将用户带到另一个应用程序

One of Android's most important features is an app's ability to send the user to another app based on an "action" it would like to perform. For example, if your app has the address of a business that you'd like to show on a map, you don't have to build an activity in your app that shows a map. Instead, you can create a request to view the address using an Intent. The Android system then starts an app that's able to show the address on a map.
Android最重要的功能之一是,应用能够将用户带到另一款应用,基于“动作”的功能。例如,如果你的应用有一个想要在地图上显示的商业地址,你就不必在你的应用中建立一个显示地图的活动。相反,您可以使用一个意图创建一个请求来查看地址。然后,Android系统启动了一个可以在地图上显示地址应用程序。
As explained in the first class, Building Your First App, you must use intents to navigate between activities in your own app. You generally do so with an explicit intent, which defines the exact class name of the component you want to start. However, when you want to have a separate app perform an action, such as "view a map," you must use an implicit intent.
正如在第一节课构建第一个应用程序中所解释的,必须使用意图在自己的应用程序的活动之间进行导航。这通常使用明确的意图来实现,这种意图定义了要启动的组件的确切类名。然而,当你想要使一个单独的应用程序执行一个动作时,比如“查看地图”,你必须使用一个隐式的意图。
This lesson shows you how to create an implicit intent for a particular action, and how to use it to start an activity that performs the action in another app.

这个课程向您展示了如何为特定的动作创建一个隐式的意图,以及如何使用它来启动另一个应用程序中的活动,以使其在执行该操作。


1.1、Build an Implicit Intent构建隐式意图

Implicit intents do not declare the class name of the component to start, but instead declare an action to perform. The action specifies the thing you want to do, such as view, edit, send, or get something. Intents often also include data associated with the action, such as the address you want to view, or the email message you want to send. Depending on the intent you want to create, the data might be a Uri, one of several other data types, or the intent might not need data at all.
隐式意图并没有声明要开始的组件的类名,而是声明要执行的操作。该操作指定了您想要做的事情,比如查看、编辑、发送或获取某些东西。意图通常还包括与操作相关的数据,比如您想要查看的地址,或者您想要发送的电子邮件消息。根据您想要创建的意图,数据可能是一个Uri,是其他几个数据类型之一,或者可能根本不需要数据。
If your data is a Uri, there's a simple Intent() constructor you can use to define the action and data.
如果你的数据是Uri,有一个简单的Intent()构造函数,你可以用它来定义动作和数据。
For example, here's how to create an intent to initiate a phone call using the Uri data to specify the telephone number:
例如,以下是如何创建一个使用Uri的数据给指定的电话号码发起一个电话呼叫的意图:
Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

When your app invokes this intent by calling startActivity(), the Phone app initiates a call to the given phone number.
当你的应用通过startActivity()方法调用这个意图时,手机应用程序会对给定的电话号码发起一个呼叫。
Here are a couple other intents and their action and Uri data pairs:
以下是一些其他的意图和他们的行动以及Uri的数据对:
  • View a map:

// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

  • View a web page:

Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

Other kinds of implicit intents require "extra" data that provide different data types, such as a string. You can add one or more pieces of extra data using the various putExtra() methods.
其他类型的隐式意图需要“extra”的数据来提供不同的数据类型,比如字符串。您可以使用各种putExtra()方法添加一个或多个额外数据。
By default, the system determines the appropriate MIME type required by an intent based on the Uri data that's included. If you don't include a Uri in the intent, you should usually use setType() to specify the type of data associated with the intent. Setting the MIME type further specifies which kinds of activities should receive the intent.
在默认情况下,系统根据包含的Uri数据来确定意图所需要的MIME类型。如果意图不包括Uri,你通常应该使用setType()来指定与意图相关的数据类型。设置MIME类型进一步指定应该接收意图的哪些类型的活动。
Here are some more intents that add extra data to specify the desired action:
这里还有一些其他的意图,它们可以添加额外的数据来指定所需的操作:
  • Send an email with an attachment: 发送带有附件的电子邮件

Intent emailIntent = new Intent(Intent.ACTION_SEND);
// The intent does not have a URI, so declare the "text/plain" MIME type
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris

  • Create a calendar event: 创建日历事件
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

Note: This intent for a calendar event is supported only with API level 14 and higher.
注意:对于日程表事件的这种意图只支持API级别14和更高。
Note: It's important that you define your Intent to be as specific as possible. For example, if you want to display an image using the ACTION_VIEW intent, you should specify a MIME type of image/*. This prevents apps that can "view" other types of data (like a map app) from being triggered by the intent.

注意:重要的是你要尽可能具体的定义你的意图。例如,如果您想使用ACTION_VIEW意图显示一个图像,您应该指定一个MIME类型的image/*。这就阻止了那些可以“查看”其他类型的数据(如地图应用)的应用程序。


1.2、Verify There is an App to Receive the Intent验证是否有应用程序来接收意图

Although the Android platform guarantees that certain intents will resolve to one of the built-in apps (such as the Phone, Email, or Calendar app), you should always include a verification step before invoking an intent.
尽管Android平台保证某些意图将会解析为内置的应用程序(例如电话、电子邮件或日历应用),但在调用意图之前,你应该始终包含一个验证步骤。
Caution: If you invoke an intent and there is no app available on the device that can handle the intent, your app will crash.
注意:如果你调用了一个意图,而设备上没有可用的应用程序来处理意图,那么你的应用就会崩溃。
To verify there is an activity available that can respond to the intent, call queryIntentActivities() to get a list of activities capable of handling your Intent. If the returned List is not empty, you can safely use the intent. For example:
要验证有一个可以响应意图的活动,请调用queryintentactivity()来获取能够处理您的意图的活动列表。如果返回的列表不是空的,您可以安全地使用意图。例如:
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
        PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

If isIntentSafe is true, then at least one app will respond to the intent. If it is false, then there aren't any apps to handle the intent.

如果isIntentSafe是真的,那么至少有一款应用会对其意图做出回应。如果它是假的,那么就没有任何应用来处理这个意图。

Note: You should perform this check when your activity first starts in case you need to disable the feature that uses the intent before the user attempts to use it. If you know of a specific app that can handle the intent, you can also provide a link for the user to download the app (see how to link to your product on Google Play).

注意:当您的活动开始时,您应该执行这个检查,以防您需要禁用在用户尝试使用它之前使用意图的特性。如果你知道一个特定的应用程序可以处理这个意图,你也可以提供一个链接让用户下载这个应用程序(看看如何在Google Play上链接到你的产品)。


1.3、Start an Activity with the Intent通过意图启动活动

Once you have created your Intent and set the extra info, call startActivity() to send it to the system. If the system identifies more than one activity that can handle the intent, it displays a dialog for the user to select which app to use, as shown in figure 1. If there is only one activity that handles the intent, the system immediately starts it.
一旦您创建了您的意图并设置了额外的信息,调用startActivity()将它发送给系统。如果系统识别出多个可以处理意图的活动,它将显示一个对话框,供用户选择要使用的应用程序,如图1所示。如果只有一个处理意图的活动,系统会立即启动它。
startActivity(intent);


Figure 1. Example of the selection dialog that appears when more than one app can handle an intent.图1所示。在多个应用程序可以处理意图时出现的选择对话框示例。

Here's a complete example that shows how to create an intent to view a map, verify that an app exists to handle the intent, then start it:

下面是一个完整的例子,展示了如何创建一个查看地图的意图,验证是否存在一个应用程序可以处理意图,然后启动它:

// Build the intent
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// Start an activity if it's safe
if (isIntentSafe) {
    startActivity(mapIntent);
}

1.4、Show an App Chooser显示应用程序选择器

Notice that when you start an activity by passing your Intent to startActivity() and there is more than one app that responds to the intent, the user can select which app to use by default (by selecting a checkbox at the bottom of the dialog; see figure 1). This is nice when performing an action for which the user generally wants to use the same app every time, such as when opening a web page (users likely use just one web browser) or taking a photo (users likely prefer one camera).

请注意,当您启动一个活动时,通过将您的意图传递给startActivity(),并且有不止一个应用程序响应意图,用户可以选择默认使用哪个应用程序(通过在对话框底部选择一个复选框;请参见图1),当用户每次都希望使用相同的应用程序时,比如打开web页面(用户可能只使用一个web浏览器)或拍照时(用户可能更喜欢一个摄像头),这是很不错的。

However, if the action to be performed could be handled by multiple apps and the user might prefer a different app each time—such as a "share" action, for which users might have several apps through which they might share an item—you should explicitly show a chooser dialog as shown in figure 2. The chooser dialog forces the user to select which app to use for the action every time (the user cannot select a default app for the action).

然而,如果要执行的操作可能是由多个应用程序,且用户每个时间可能喜欢不同的应用程序,比如一个“共享”行动,因为用户可以共享一个东西的应用程序可能几个,你应该明确显示一个选择器对话框,如图2所示。选择器对话框每次都要强制用户选择使用哪个应用程序(用户不能选择一个默认的应用程序)。



Figure 2. A chooser dialog. 图2。一个选择器对话框。

To show the chooser, create an Intent using createChooser() and pass it to startActivity(). For example:

要显示选择器,请使用createchoser()创建一个意图,并将其传递给startActivity()。例如:

Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);

// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

This displays a dialog with a list of apps that respond to the intent passed to the createChooser() method and uses the supplied text as the dialog title.

这将显示一个对话框,其中有一个应用程序列表,它响应传递给createchoser()方法的意图,并使用所提供的文本作为对话框标题。


2、Getting a Result from an Activity从活动中获得结果

Starting another activity doesn't have to be one-way. You can also start another activity and receive a result back. To receive a result, call startActivityForResult() (instead of startActivity()).

启动另一个活动并不一定是单向的。您还可以启动另一个活动并接收结果。要接收一个结果,调用startActivityForResult()(而不是startActivity())。

For example, your app can start a camera app and receive the captured photo as a result. Or, you might start the People app in order for the user to select a contact and you'll receive the contact details as a result.

例如,你的应用可以启动一个照相应用程序,然后接收拍摄到的照片作为返回的结果。或者,你可以启动用户应用程序,让用户选择联系人,你会收到联系人的详细信息作为结果。

Of course, the activity that responds must be designed to return a result. When it does, it sends the result as another Intent object. Your activity receives it in the onActivityResult() callback.

当然,响应的活动必须设计去返回结果。当它执行时,它将结果作为另一个意图对象发送。您的活动在onActivityResult()回调中接收到它。

Note: You can use explicit or implicit intents when you call startActivityForResult(). When starting one of your own activities to receive a result, you should use an explicit intent to ensure that you receive the expected result.

注意:在调用startActivityForResult()时,可以使用显式或隐式意图。当您启动自己的一个活动来接收结果时,您应该使用一个显式的意图来确保您接收到预期的结果。


2.1、Start the Activity启动活动

There's nothing special about the Intent object you use when starting an activity for a result, but you do need to pass an additional integer argument to the startActivityForResult() method.

在为结果启动活动时,您使用的意图对象没有什么特别之处,但是您确实需要将一个额外的整数参数传递给startActivityForResult()方法。

The integer argument is a "request code" that identifies your request. When you receive the result Intent, the callback provides the same request code so that your app can properly identify the result and determine how to handle it.

整数参数是标识请求的“请求码”。当接收到结果意图时,回调提供相同的请求代码,以便您的应用程序能够正确地识别结果并决定如何处理它。

For example, here's how to start an activity that allows the user to pick a contact:

例如,下面是如何启动一个允许用户选择联系人的活动:

static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

2.2、Receive the Result接收这个结果

When the user is done with the subsequent activity and returns, the system calls your activity's onActivityResult() method. This method includes three arguments:

当用户完成随后的活动并且返回时,系统将调用您的活动 onActivityResult() 方法。这种方法包括三个参数:

  • The request code you passed to startActivityForResult().您传递给startActivityForResult()的请求码。

  • A result code specified by the second activity. This is either RESULT_OK if the operation was successful or RESULT_CANCELED if the user backed out or the operation failed for some reason. 由第二个活动指定的结果码。如果操作成功返回RESULT_OK ,如果用户退出或由于某种原因导致操作失败,结果被取消返回RESULT_CANCELED。

  • An Intent that carries the result data. 带有结果数据的意图

For example, here's how you can handle the result for the "pick a contact" intent:

例如,以下是您如何处理“选择联系人”意图的结果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // The user picked a contact.
            // The Intent's data Uri identifies which contact was selected.

            // Do something with the contact here (bigger example below)
        }
    }
}

In this example, the result Intent returned by Android's Contacts or People app provides a content Uri that identifies the contact the user selected.

在这个例子中,结果意图是通过Android联系人返回,或者用户应用程序提供了一种内容Uri,可以用来识别用户所选择的联系人。

In order to successfully handle the result, you must understand what the format of the result Intent will be. Doing so is easy when the activity returning a result is one of your own activities. Apps included with the Android platform offer their own APIs that you can count on for specific result data. For instance, the People app always returns a result with the content URI that identifies the selected contact, and the Camera app returns a Bitmap in the "data" extra (see the class about Capturing Photos).

为了成功地处理结果,您必须理解结果意图的格式是什么。当返回结果的活动是您自己的活动时,这样做很容易。Android平台上的应用程序提供了自己的api,你可以依靠这些api来获得特定的结果数据。例如,用户应用程序总是会返回一个结果,其中包含指定联系人的内容URI,而相机应用程序会在“数据”中返回一个位图(查看关于获取照片的类)。

Bonus: Read the contact data

附加信息:读取联系人数据

The code above showing how to get a result from the People app doesn't go into details about how to actually read the data from the result, because it requires more advanced discussion about content providers. However, if you're curious, here's some more code that shows how to query the result data to get the phone number from the selected contact:

上面的代码显示了如何从用户应用程序获取结果,但没有详细说明如何从结果中读取数据,因为这需要对内容提供者进行更深入的讨论。但是,如果您很好奇,这里有更多的代码显示如何查询结果数据以从所选的联系人获取电话号码:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // Get the URI that points to the selected contact
            Uri contactUri = data.getData();
            // We only need the NUMBER column, because there will be only one row in the result
            String[] projection = {Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using CursorLoader to perform the query.
            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();

            // Retrieve the phone number from the NUMBER column
            int column = cursor.getColumnIndex(Phone.NUMBER);
            String number = cursor.getString(column);

            // Do something with the phone number...
        }
    }
}

Note: Before Android 2.3 (API level 9), performing a query on the Contacts Provider (like the one shown above) requires that your app declare the READ_CONTACTS permission (see Security and Permissions). However, beginning with Android 2.3, the Contacts/People app grants your app a temporary permission to read from the Contacts Provider when it returns you a result. The temporary permission applies only to the specific contact requested, so you cannot query a contact other than the one specified by the intent's Uri, unless you do declare the READ_CONTACTS permission.

注意:在Android 2.3(API级别9)之前,在联系人提供者上执行查询(如上面所示)要求您的应用程序声明READ_CONTACTS权限(请参阅安全性和权限)。然而,从Android 2.3开始,联系人/联系人应用程序允许你的应用获得一个临时许可,当它返回你的结果时,你可以从联系人列表中读取信息。临时许可只适用于请求的特定联系人,因此,除非你确实声明了READ_CONTACTS权限,否则你不能查询其他联系人的联系。


3、Allowing Other Apps to Start Your Activity允许其他应用启动你的活动

The previous two lessons focused on one side of the story: starting another app's activity from your app. But if your app can perform an action that might be useful to another app, your app should be prepared to respond to action requests from other apps. For instance, if you build a social app that can share messages or photos with the user's friends, it's in your best interest to support the ACTION_SEND intent so users can initiate a "share" action from another app and launch your app to perform the action.

之前的两节课程集中在故事的一个方面:从你的应用中启动另一个应用的活动,但是如果你的应用可以执行一个对另一个应用有用的操作,你的应用应该准备好响应来自其他应用的行动请求。例如,如果你创建了一个社交应用,可以与用户的好友分享消息或照片,那么支持ACTION_SEND意图是你最感兴趣的,这样用户就可以从另一个应用发起“分享”行动,并启动你的应用来执行这个动作。

To allow other apps to start your activity, you need to add an <intent-filter> element in your manifest file for the corresponding <activity> element.

为了让其他应用程序启动您的活动,您需要在您的清单文件中添加一个<intent-filter>元素,在对应的<activity>元素内。

When your app is installed on a device, the system identifies your intent filters and adds the information to an internal catalog of intents supported by all installed apps. When an app calls startActivity() or startActivityForResult(), with an implicit intent, the system finds which activity (or activities) can respond to the intent.

当你的应用安装在设备上时,系统会识别你的意图过滤器,并将这些信息添加到一个内部意图目录中,这个目录被所有已安装的应用支持。当一个应用程序调用startActivity()或startActivityForResult(),带有隐式意图时,系统会寻找哪个活动(或活动)可以对意图作出响应。


3.1、Add an Intent Filter添加意图过滤器

In order to properly define which intents your activity can handle, each intent filter you add should be as specific as possible in terms of the type of action and data the activity accepts.

为了正确地定义您的活动可以处理的意图,您所添加的每个意图过滤器应该在动作类型和活动所接受的数据上尽可能具体。

The system may send a given Intent to an activity if that activity has an intent filter fulfills the following criteria of the Intent object:

如果该活动有一个意图过滤器满足意图对象的以下条件,系统可能会将给定的意图发送给一个活动。

Action

A string naming the action to perform. Usually one of the platform-defined values such as ACTION_SEND or ACTION_VIEW. 一个命名执行动作的字符串。通常是一个平台定义的值,例如ACTION_SEND或ACTION_VIEW。

Specify this in your intent filter with the <action> element. The value you specify in this element must be the full string name for the action, instead of the API constant (see the examples below). 在您的意图过滤器中指定<action>元素。您在这个元素中指定的值必须是操作的完整字符串名称,而不是API常量(参见下面的示例)。

Data

A description of the data associated with the intent. 对与意图相关的数据的描述。

Specify this in your intent filter with the <data> element. Using one or more attributes in this element, you can specify just the MIME type, just a URI prefix, just a URI scheme, or a combination of these and others that indicate the data type accepted. 在您的意图过滤器中指定这个<data>元素。在这个元素中使用一个或多个属性,您可以指定MIME类型,或是一个URI前缀,或是一个URI方案,或者是这些和表示所接受的数据类型的组合。

Note: If you don't need to declare specifics about the data Uri (such as when your activity handles to other kind of "extra" data, instead of a URI), you should specify only the android:mimeType attribute to declare the type of data your activity handles, such as text/plain or image/jpeg. 注意:如果你不需要对Uri的数据进行详细说明(比如当你的活动处理其他的“extra”数据时,而不是一个Uri),你应该只指定android:mimeType属性来声明你的活动处理的数据类型,比如text/plain或image/jpeg。

Category

Provides an additional way to characterize the activity handling the intent, usually related to the user gesture or location from which it's started. There are several different categories supported by the system, but most are rarely used. However, all implicit intents are defined with CATEGORY_DEFAULT by default. 提供了一种附加的方式来描述处理意图的活动,通常与开始时的用户手势或位置相关。系统支持有几个不同的类别,但大多数都很少使用。然而,所有的隐式意图都是默认定义为CATEGORY_DEFAULT。

Specify this in your intent filter with the <category> element. 在您的意图过滤器中通过<category>元素指定。


In your intent filter, you can declare which criteria your activity accepts by declaring each of them with corresponding XML elements nested in the <intent-filter> element.

在您的意图过滤器中,您可以声明您的活动接受哪些标准,通过相应的XML元素将其声明,嵌套在<intent-filter>元素中。

For example, here's an activity with an intent filter that handles the ACTION_SEND intent when the data type is either text or 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>

Each incoming intent specifies only one action and one data type, but it's OK to declare multiple instances of the <action>, <category>, and <data> elements in each <intent-filter>.

每个传入的意图只指定一个动作和一个数据类型,但是可以在每个<intent-filter>元素中声明多个<action>、 <category>和<data>元素的实例。

If any two pairs of action and data are mutually exclusive in their behaviors, you should create separate intent filters to specify which actions are acceptable when paired with which data types.

如果任何两对action和data在它们的行为中是互斥的,那么您应该创建单独的意图过滤器,以指定在与哪些数据类型成对时可以接受哪些操作。

For example, suppose your activity handles both text and images for both the ACTION_SEND and ACTION_SENDTO intents. In this case, you must define two separate intent filters for the two actions because a ACTION_SENDTO intent must use the data Uri to specify the recipient's address using the send or sendto URI scheme. For example:

例如,假设您的活动同时处理ACTION_SEND和ACTION_SENDTO意图的文本和图像。在这种情况下,你必须为这两种行为定义两个独立的意图过滤器,因为一个ACTION_SENDTO意图必须使用数据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>

Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare it in your intent filter, no implicit intents will resolve to your activity.

注意:为了接收隐式意图,您必须在意图过滤器中包含CATEGORY_DEFAULT类别。方法startActivity()和startActivityForResult()对所有意图都进行了处理,就好像它们声明了CATEGORY_DEFAULT类别一样。如果您没有在您的意图过滤器中声明它,那么没有任何隐式意图将解析到您的活动。

For more information about sending and receiving ACTION_SEND intents that perform social sharing behaviors, see the lesson about Receiving Simple Data from Other Apps.

关于发送和接收执行社交分享行为的ACTION_SEND意图的更多信息,请参阅从其他应用程序接收简单数据的经验。


3.2、Handle the Intent in Your Activity在你的活动中处理意图

In order to decide what action to take in your activity, you can read the Intent that was used to start it.

为了决定在您的活动中采取什么动作,您可以阅读用于启动该活动的意图。

As your activity starts, call getIntent() to retrieve the Intent that started the activity. You can do so at any time during the lifecycle of the activity, but you should generally do so during early callbacks such as onCreate() or onStart().

当您的活动开始时,调用getIntent()来检索启动该活动的意图。在活动生命周期的任何时候,您都可以这样做,但是您应该在早期的onCreate()或onStart()回调方法中这样做。

For example:

举个例子:

@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 ...
    }
}

3.3、Return a Result返回结果

If you want to return a result to the activity that invoked yours, simply call setResult() to specify the result code and result Intent. When your operation is done and the user should return to the original activity, call finish() to close (and destroy) your activity. For example:

如果您想将结果返回到调用您的活动,只需调用setResult()来指定结果代码和结果意图。当您的操作完成并且用户应该返回到原始的活动时,调用finish()来关闭(并销毁)您的活动。例如:

// 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();

You must always specify a result code with the result. Generally, it's either RESULT_OK or RESULT_CANCELED. You can then provide additional data with an Intent, as necessary.

您必须始终给结果指定结果码。通常,它要么是RESULT_OK,要么是RESULT_CANCELED。必要时,您可以在意图中添加附加的数据。

Note: The result is set to RESULT_CANCELED by default. So, if the user presses the Back button before completing the action and before you set the result, the original activity receives the "canceled" result.

注意:结果被默认设置为RESULT_CANCELED。因此,如果用户在完成操作之前,并且在设置结果之前按下Back按钮,原始的活动将收到“取消”的结果。

If you simply need to return an integer that indicates one of several result options, you can set the result code to any value higher than 0. If you use the result code to deliver an integer and you have no need to include the Intent, you can call setResult() and pass only a result code. For example:

如果您只需要返回一个表示多个结果选项之一的整数,那么您可以将结果码设置为高于0的任何值。如果使用结果码来传递一个整数,并且不需要包含意图,那么可以调用setResult()并只传递结果码。例如:

setResult(RESULT_COLOR_RED);
finish();

In this case, there might be only a handful of possible results, so the result code is a locally defined integer (greater than 0). This works well when you're returning a result to an activity in your own app, because the activity that receives the result can reference the public constant to determine the value of the result code.

在这种情况下,可能会有少数可能的结果,所以结果码是一个本地定义整数(大于0)。当你返回一个结果给你自己应用的活动时会很好,因为收到结果的活动可以引用这个公共常量来确定结果代码。

Note: There's no need to check whether your activity was started with startActivity() or startActivityForResult(). Simply call setResult() if the intent that started your activity might expect a result. If the originating activity had called startActivityForResult(), then the system delivers it the result you supply to setResult(); otherwise, the result is ignored.

注意:没有必要检查您的活动是否从startActivity()或startActivityForResult()开始。如果启动活动的意图可能想要得到结果,那么简单地调用setResult()。如果起始活动调用startActivityForResult(),那么系统将你在setResult()中提供的结果传递给它;否则,结果将被忽略。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值