与其他应用交互之简单使用Intent

向另一个应用发送数据

Android 最重要的功能之一是应用能够基于它要执行的“操作”向另一个应用发送数据。 例如,如果您的应用有您要在地图上显示的公司地址,您无需在显示地图的应用中构建 Activity。 而是可以创建使用 Intent 查看地址的请求。Android 系统之后启动可以在地图上显示该地址的应用。
您必须使用 Intent 在自己应用中的 Activity 之间进行导航。 您通常使用显式 Intent 执行此操作,该 Intent 定义您希望启动的组件的确切类名称。 但是,当您希望另一应用执行操作时,比如“查看地图”,您必须使用隐式 Intent。

本博文向您展示如何针对特定操作创建隐式 Intent,以及如何使用该 Intent 启动在另一个应用中执行操作的 Activity。

构建隐式 Intent

隐式 Intent 不声明要启动的组件的类名称,而是声明要执行的操作。 该操作指定您要执行的操作,比如查看、编辑、发送或 获取 某项。 Intent 通常还包含与操作关联的数据,比如您要查看的地址或您要发送的电子邮件消息。根据要创建的 Intent,数据可能是 Uri、多种其他数据类型之一,或 Intent 可能根本就不需要数据。
如果您的数据是 Uri,您可以使用一个简单的 Intent() 构造函数来定义操作和数据。

例如,此处显示如何使用指定电话号码的 Uri 数据创建发起电话呼叫的 Intent:

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

当您的应用通过调用 startActivity() 调用此 Intent 时,“电话”应用会发起向指定电话号码的呼叫。

这里有一些其他 Intent 及其操作和 Uri 数据对:

查看地图:

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

查看网页:

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

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

默认情况下,系统基于所包含的 Uri 数据确定 Intent 需要的相应 MIME 类型。如果您未在 Intent 中包含 Uri,您通常应使用 setType() 指定与 Intent 关联的数据的类型。 设置 MIME 类型可进一步指定哪些类型的 Activity 应接收 Intent。

此处有更多添加额外数据以指定所需操作的 Intent:

发送带附件的电子邮件:

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

创建日历事件:

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 Intent 显示图像,您应指定 MIME 类型 image/*。这可防止可“查看”数据的其他类型的应用(比如地图应用)被 Intent 触发。

验证是否存在接收 Intent 的应用

尽管 Android 平台保证某些 Intent 可以分解为内置应用之一(比如,“电话”、“电子邮件”或“日历”应用),您应在调用 Intent 之前始终包含确认步骤。
注意:如果您调用了 Intent,但设备上没有可用于处理 Intent 的应用,您的应用将崩溃。
要确认是否存在可响应 Intent 的可用 Activity,请调用 queryIntentActivities() 来获取能够处理您的 Intent 的 Activity 列表。如果返回的 List 不为空,您可以安全地使用该 Intent。例如:

PackageManager packageManager = [getPackageManager()](https://developer.android.google.cn/reference/android/content/Context.html#getPackageManager())
;List activities = packageManager.queryIntentActivities(intent,        PackageManager.MATCH_DEFAULT_ONLY);boolean isIntentSafe = activities.size() > 0;

如果 isIntentSafe 是 true,则至少有一个应用将响应该 Intent。 如果它是 false,则没有任何应用处理该 Intent。
注:在您需要在用户尝试使用它之前停用使用该 Intent 的功能时,您应在 Activity 初次启动时执行此检查。 如果您了解可处理 Intent 的特定应用,您还可以为用户提供下载该应用的链接(请参阅如何在 Google Play 链接到您的产品)

启动具有 Intent 的 Activity

一旦您已创建您的 Intent 并设置 extra 信息,调用 startActivity() 将其发送给系统。如果系统识别可处理 Intent 的多个 Activity,它会为用户显示对话框供其选择要使用的应用,如图 1 所示。如果只有一个 Activity 处理 Intent,系统会立即将其启动。

startActivity(intent);

此处显示完整的示例:如何创建查看地图的 Intent,验证是否存在处理 Intent 的应用,然后启动它:

// 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()](https://developer.android.google.cn/reference/android/content/Context.html#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 时,有多个应用响应 Intent,用户可以选择默认使用哪个应用(通过选中对话框底部的复选框;见图 1)。当执行用户通常希望每次使用相同应用进行的操作时,比如当打开网页(用户可能只使用一个网络浏览器)或拍照(用户可能习惯使用一个相机)时,这非常有用。

但是,如果要执行的操作可由多个应用处理并且用户可能 习惯于每次选择不同的应用 — 比如“共享”操作, 用户有多个应用分享项目 — 您应明确显示选择器对话框, 如图 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 chooser
Intent chooser = Intent.createChooser(intent, title);

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

这将显示一个对话框,其中包含响应传递给 createChooser() 方法的 Intent 的应用列表,并且将提供的文本用作对话框标题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容