Sending the User to Another App(使用户跳转到其它应用程序)
该系列文章是我在学习Google开发者文档时结合谷歌翻译和自身理解编写的,希望对学习Android开发的朋友带来些便利,由于个人翻译水平有限,所以内容包含原文和译文,希望浏览者结合理解,以免步入我可能错译的误区。
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其中一个最重要的特性就是一个应用程序具有基于一个“action”(行为)来使用户跳转到另一个想要跳转的应用程序中的能力。比如,如果您的应用程序想在地图上显示一个企业的地址,你不需要去为了显示地图而特地去建立一个活动界面。你完全可以通过创建一个intent(意向)来请求显示地址,然后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.
就像第一节课中讲述的那样,建立你的第一个应用程序,您必须使用intent(意图)在自己的应用程序活动之间进行导航。您通常使用的是明确意图(显示intent),它明确定义了你想要启动组件的确切类名。但是,如果你想使另外一个单独的应用程序去执行一个操作,如“查看地图”,你必须使用一个隐含的意图(隐式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.
本课将向您展示如何创建一个隐含的意图(隐式intent)进行特定的操作,以及如何使用它来启动其他应用程序去启动一个活动界面来执行指定的动作。
Build an Implicit Intent(建立一个隐含意图(隐式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.
隐式意图(隐式intent)不定义启动组件的类名,而是声明要执行的action(行为、操作)。该操作指定你想做的事情,如查看,编辑,发送,或获取某些东西。意图往往还包含与action(动作)相关的数据,比如你要查看的地址,或者您要发送的电子邮件的消息内容。根据您要创建的intent(意图),数据可能是一个Uri或者其他数据类型,或者您定义的intent(意图)可能根本不需要添加数据。
If your data is a Uri, there’s a simple Intent() constructor you can use define the action and data.
如果你的数据是一个Uri,那么这里有一个简单的intent()构造函数可以供你去定义该intent(意向)的action(行为、操作)和数据。
For example, here’s how to create an intent to initiate a phone call using the Uri data to specify the telephone number:
例如,下面是如何创建一个使用URL数据来指定电话号码发起呼叫的intent(意图):
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:
这里有一些其它的intent(意图)定义以及他们各自对应的action(行为)和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 z参数是地图缩放层级 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.
其他类型的隐式意图需要提供不同数据类型的“额外”数据,诸如字符串。可以使用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.
默认情况下,系统基于intent(意图)包含的Uri数据来确定其所需的合适的MIME类型。如果你没有在intent(意向)中包含一个Uri,你通常应该使用setType()方法来指定intent(意图)相关的数据类型。设置MIME类型还会指定哪些类型的活动可以接收到这个意图。
Here are some more intents that add extra data to specify the desired action:
下面是一些intent(意图)定义以及其各自对应包含的额外数据和期望的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 //这个intent不包含URI,所以定义了“text/plain”类型的MIME类型 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 //您也可以通过传递URI的ArrayList来附加多个项
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.
注:此日历事件intent(意图)仅支持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.*
注:您应该使您定义的intent(意图)尽可能具体,这一点很重要。例如,如果您想使用ACTION_VIEW意图来显示图像,您应该指定一个image/的MIME类型。这样可以防止可以“查看”其它数据类型的应用程序(例如地图应用)会被触发。*
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平台保证某些意图将会解析为内置的应用程序意图(如电话,电子邮件或日历应用),但你还是应该包含一个调用intent(意图)之前的验证步骤。
Caution: If you invoke an intent and there is no app available on the device that can handle the intent, your app will crash.
注意:如果你调用了一个intent(意图),但设备上并没有可以操作这个intent的应用程序,那么你的应用程序将会崩溃。
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:
要验证是否有活动可以对intent(意图)做出回应,调用queryIntentActivities()方法来获得能够处理你定义的意图的活动列表。如果返回的列表不是空的,那么你可以放心地使用定义的意图了。 例如:
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的值是true,那么至少有一个应用程序将会对这个意图做出回应。如果是false,那么不会有任何应用程序来处理这个意图。
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).
注意:当用户尝试使用这个intent(意图)功能之前,你需要在活动界面启动以后先执行上面的检查,以免你需要禁用这个intent(意图)功能。如果你知道一个特定的应用程序可以处理这个intent(意图),你也可以提供一个链接来供用户下载相应的应用程序(查看如何在Google Play上链接到你的产品)。
Start an Activity with the Intent(通过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.
一旦创建好了你的intent(意图),并设置好了额外信息,那么调用startActivity()将其发送到了系统中。如果系统识别到多个的活动可以处理这个intent(意图),它就会为用户弹出一个对话框,用于供用户选择要使用的应用程序,如图1,如果仅存在一个活动可以处理这个intent(意图),系统则会立即启动它。
startActivity(intent);
图1:当检测到多个活动能响应intent时弹出的对话框举例
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:
以下是一个完整的例子演示了如何创建一个查看地图的intent(意图),并验证了存在一个应用程序可以响应处理这个意图,然后开始调用这个intent(意图):
// Build the intent //创建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 //检测该intent的解决方法(响应活动列表) 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); }
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()方法并将你的intent(意图)传递了进入,这时如果有多个应用程序响应意图,用户可以选择默认情况下要使用的应用程序(通过选择在对话框底部的复选框;见图1)。这样系统就会在每次执行该动作时默认使用相同的应用程序,这是很好的,例如打开一个网页(用户可能只使用一个网络浏览器),或者拍照(用户可能更喜欢使用某个摄像头)时。
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。选择对话框强制用户每次都需要选择要响应这个动作的应用程序(用户无法选择动作的默认应用)。
图2:一个选择对话框
To show the chooser, create an Intent using createChooser() and pass it to startActivity(). For example:
要显示选择器,创建一个使用createChooser()的意图,并把它传递给startActivity()。 例如:
Intent intent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. //总是使用字符串作为UI文本 // This says something like "Share this photo with" //这里显示类似“分享照片到”意思的语句 String title = getResources().getString(R.string.chooser_title); // Create intent to show chooser //创建一个选择器intent(意图) Intent chooser = Intent.createChooser(intent, title); // Verify the intent will resolve to at least one activity //检测至少有一个活动可以响应这个intent(意图) 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.
这样就会显示一个可以响应传递给createChooser()方法中传入的intent(意图)的应用程序列表,并且使用提供的文本作为标题。
来自: http://blog.csdn.net/u014031072/article/details/51545545