使用隐式Intent启动其他APP

来源:互联网 发布:电气接线仿真软件 编辑:程序博客网 时间:2024/06/09 19:55

Android的最重要功能之一就是APP能够根据“Action”跳转到另一个APP。例如,如果您希望在地图上显示出您APP中的商家地址,则您不必在APP中建立一个显示地图的Activity,但您可以使用Intent创建一个查看地址的请求。然后Android系统启动一个能够在地图上显示地址的APP。

您可以用显式Intent实现APP内各Activity之间的切换,显式Intent定义了要启动的目标组件的确切类名。但是,如果要调用另一个APP来执行某个操作,例如“查看地图”,则必须使用隐式Intent。

本课程将向您展示如何为特定Action创建隐式Intent,以及如何使用它来启动其他APP中执行此Action的Activity。

建立隐式Intent

隐式Intent不声明要启动的组件的类名,而是声明要执行的Action。该Action指定您要执行的操作,例如view,edit,send或get某些内容。Intent通常还包括与Action相关联的Data,例如要查看的地址或要发送的电子邮件。根据您要创建的Intent,Data可能是Uri或其他几种数据类型之一,或者Intent可能根本不需要Data。

如果您的数据是Uri,则可以使用Intent()构造函数来定义Action和Data。例如,以下展示如何使用Uri数据来指定电话号码,并用此Uri来创建拨号Intent。

Uri number = Uri.parse("tel:5551234");Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

当您的APP通过startActivity()来调用此Intent时,Phone APP会发起对给定电话号码的呼叫。

下面有一些其他Intent与其对应的Action和Uri数据:

•查看地图:

// Map point based on addressUri 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 levelIntent mapIntent = new Intent(Intent.ACTION_VIEW, location);

•查看网页:

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

其他类型的隐式Intent需要提供不同数据类型的“extra”数据,例如字符串。您可以使用putExtra()方法添加一个或多个额外的数据。

默认情况下,系统根据包含的Uri数据确定Intent所需的MIME类型。如果Intent中不包含Uri,则通常应该使用setType()来指定与intent相关联的数据类型。设置MIME类型可以进一步指定哪些类型的Activity应该接收Intent。

下面是一些Intent,通过添加extra data来指定所需的操作:
•发送带有附件的电子邮件:

Intent emailIntent = new Intent(Intent.ACTION_SEND);// The intent does not have a URI, so declare the "text/plain" MIME typeemailIntent.setType(HTTP.PLAIN_TEXT_TYPE);emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipientsemailIntent.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

•创建日历事件:

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");

注意:只有API级别14及更高版本才支持这个日历事件的Intent。

注意:您应该尽可能具体地定义Intent。例如,如果要使用ACTION_VIEW 来显示图像,则应指定MIME类型为image/*。这可以防止可以“查看”其他类型数据的APP(如地图应用程序)被此Intent启动。

验证是否有接收Intent的APP

虽然Android平台保证每个Intent都会有一个内置APP(如电话,电子邮件或日历APP)来接收,但在调用Intent之前仍需验证是否有接收此Intent的APP。
注意:如果您调用Intent,但是设备上没有可以处理该Intent的APP,您的APP将Crash。

为验证是否有可用的Activity可以响应Intent,请调用queryIntentActivities()获取能够处理您的Intent的Activity列表,如果返回的列表不为空,则可以安全地使用该Intent。例如:

PackageManager packageManager = getPackageManager();List activities = packageManager.queryIntentActivities(intent,        PackageManager.MATCH_DEFAULT_ONLY);boolean isIntentSafe = activities.size() > 0;

如果isIntentSafe是true,那么至少有一个APP能响应此Intent;如果为false,那么没有APP能处理此Intent。
注意:当您应该在Activity首次启动时就执行此检查,以防在用户尝试使用该功能之前禁用使用此Intent的功能。如果您知道哪些特定APP可以处理此Intent,那么可以向用户提供下载此APP的链接(请参阅link to your product on Google Play)

用Intent启动Activity

创建Intent并设置extra信息后,调用startActivity()将其发送到系统。如果系统识别出有多个Activity可以处理此Intent,它将显示一个对话框,供用户选择要使用哪个APP,如图1所示。如果只有一个Activity能处理Intent,那么系统立即启动它。

startActivity(intent);

这里写图片描述
图1.当多个APP可以处理Intent时显示的选择对话框。

以下是一个完整的示例,显示如何创建查看地图的Intent,验证是否存在处理此Intent的APP,并启动它:

// Build the intentUri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);// Verify it resolvesPackageManager packageManager = getPackageManager();List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);boolean isIntentSafe = activities.size() > 0;// Start an activity if it's safeif (isIntentSafe) {    startActivity(mapIntent);}

显示应用选择器

当您把Intent传递给startActivity()启动Activity时,如果有多个APP响应此Intent,用户可以选择默认使用哪个APP(通过选择对话框底部的复选框,见图1右下角红色框内)。这适用于用户喜欢使用同一个APP来完成某个操作,如打开网页(用户可能只使用某个浏览器)或拍照(用户可能只喜欢某个相机)。

但是,如果有多个APP响应Intent,用户可能更喜欢每次使用不同的APP。如分享操作,用户可能有几个APP支持分享功能,那么您应该显式地显示一个选择对话框,如图2所示。选择对话框强制用户每次选择要使用哪个APP完成此操作(用户无法为该操作选择默认APP)。
这里写图片描述
图2.选择对话框。
要显示选择器,使用createChooser()创建一个Intent并将其传递给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 chooserIntent chooser = Intent.createChooser(intent, title);// Verify the intent will resolve to at least one activityif (intent.resolveActivity(getPackageManager()) != null) {    startActivity(chooser);}

这将显示一个对话框,其中展示能响应此Intent的APP列表,并使用提供的文本作为对话标题。

原创粉丝点击