注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接:http://developer.android.com/training/basics/intents/sending.html


Android的一个最重的特性就是一个应用可以将用户带领到另一个应用的能力,这一切基于的是一个应用期望表现的“行为(action)”。例如,如果你的应用有一个你期望显示在地图上的地址,你不需要在你的应用中构建一个显示地图的Activity,你只需要通过使用Intent来创建一个查勘地址的需求。之后Android系统会自动启动一个可以在地图上显示地址的应用。

如同在第一节课Building Your First App(博客链接:http://www.cnblogs.com/jdneo/p/3438954.html)所说的,你必须使用intents在你的应用的Activity之间转换。一般你通过显示intent来做这件事情,这将指明你希望启动的组件的类名。然而,当你希望通过另一个应用执行一个行为,比如“查看地图”,你就必须使用一个隐式的intent。

这节课将向你展示如何为一个特定的行为创建一个隐式intent,以及如何使用它启动一个其它应用的Activity来执行这个行为。

一). 构建一个隐式的Intent

隐式Intent不声明要启动组件的类名,而是声明一个要执行的行为。该行为指定了你希望做的事情,比如查看,编辑,发送或者获取某些东西。Intents也经常包含与该行为有关的数据,比如你希望查看的地址,或者你希望发送的邮件内容。根据你希望创建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);

其它类型的隐式Intents需要“extra”数据来提供不同的数据类型,比如字符串。你通过使用不同的putExtra()方法来添加一个或多个“extra”数据。

默认的,系统会基于intent所包含的Uri数据,来指定它所需要的恰当MIME类型。如果你在intent中不包含一个Uri,你应该使用setType()来指定与该intent所关联的数据类型。设置MIME类型会进一步特定什么类型的Activity将会接受这个intent。

下面是一些intent例子,它们通过添加额外的数据来定义希望的行为:

  • 发送一个有附件的Email:
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");

Note:

这个日历事件的Intent仅在API Level 14或更高的平台上被支持。

Note:

将你的Intent定义的越明确越好!例如,如果你希望使用ACTION_VIEW的intent来展示一个图片,你应该特定MIME类型为“image/*”。这将防止可以查看其他数据类型的应用(比如一个地图阅览器)被这个intent激活。

二). 确认有一个应用能接受此Intent

虽然Android平台保证某个Intent将会由一个内置的应用所处理(比如:电话,电子邮件或者日历等应用),但是你在激活一个intent前包含一个确认的步骤。

Caution:

如果你激活了一个在设备中没有任何一个应用能够处理该事务的intent,那么你的应用将会崩溃。

为了确认有一个应用能够正确响应这个intent,调用queryIntentActivities()来得到一个能够处理你的Intent的activity清单。如果返回的List不为空,你可以安全地使用这个intent。例如:

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

如果isIntentSafe为真,那就说明至少有一个应用能够正确响应这个intent。如果为假,那就说明没有任何应用能够处理这个intent。

Note:

你应该在你的应用第一次启动时执行这个检查,这样你就可以禁用使用该intent的功能特性,防止用户尝试去使用它。如果你知道某个特定的应用能够处理这个intent,你也可以给用户提供链接来让用户下载这个应用(可也查阅:link to your product on Google Play

三). 通过Intent启动一个Activity

一旦你创建了你的Intent并且设置了额外的信息,你可以调用startActivity()将它发送给系统。如果系统发现有不止一个acitivity可以处理这个intent,它会向用户显示一个对话框,让用户选择要启动哪一个应用,如图1所示。如果只有一个应用能够处理这个intent,那么系统会立即直接启动它。

startActivity(intent);

图1. 当有多个应用能够处理该intent时,系统所显示的选择对话框

下面是一个完整的例子,它显示了如何创建一个intent来浏览一个地图,然后确认是否存在应用能够处理它,然后启动它:

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

四). 显示一个应用选择器(App Chooser)

注意到当你将你的Intent传递给startActivity()来启动一个Activity时,如果有多个应用可以正确响应这个intent,用户可以选择默认使用哪个程序(在对话框底部勾选复选框,见图1)。当用户每次都希望使用相同的应用来处理该事务时(比如打开一个网页时,用户可能会喜欢只用一个浏览器,或者拍摄一个照片,用户可能只喜欢用一款相机应用),此时这么做是不错的。

然而,如果这个intent行为可以被多个应用处理,同时,用户每次可能期望使用不同的应用——比如“分享”这一行为,用户可能有多个应用能够分享某一个项目。此时你应该显式地展现一个选择应用的对话框,如图2所示。这个对话框强制用户在每次执行该操作时,选择一个自己期望的应用来处理该事务(用户不能选择一个默认的应用来处理)。

图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 and start the chooser
Intent chooser = Intent.createChooser(intent, title);
startActivity(chooser);

这样将会显示一个对话框,里面显示了能够处理传递给createChooser()的intent的应用清单,对话框的标题是代码中指定的文本。

【Android Developers Training】 28. 将用户带领到另一个应用的更多相关文章

  1. 【Android Developers Training】 27. 序言:和其它应用交互

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. 【Android Developers Training】 107. 认知用户当前的行为

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. 【Android Developers Training】 9. 覆盖于布局之上的Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  4. 【Android Developers Training】 8. 定义Action Bar风格

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  5. 【Android Developers Training】 7. 添加Action Buttons

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. 【Android Developers Training】 6. 配置Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 【Android Developers Training】 5. 序言:添加Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. 【Android Developers Training】 4. 启动另一个Activity

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. 【Android Developers Training】 3. 构建一个简单UI

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

随机推荐

  1. Windows下安装虚拟机和Linux

    首先必须开启BIOS中的虚拟化 常见计算机BIOS快捷键: 联想E431 F1dell F2微星 DELETE 默认是开启HP pavilion notebook 15-ab527TX F9和F10m ...

  2. tomcat流程原理解析

    tomcat的启动是通过Bootstrap类的main方法(tomcat6开始也可以直接通过Catlina的main启动) Bootstrap的启动 Bootstrap的main方法先new了一个自己 ...

  3. 求序列的和,杭电0j-2058

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=2058 [Problem Description] Given a sequence 1,2,3,... ...

  4. MHA在线切换的步骤及原理

    在日常工作中,会碰到如下的场景,如mysql数据库升级,主服务器硬件升级等,这个时候就需要将写操作切换到另外一台服务器上,那么如何进行在线切换呢?同时,要求切换过程短,对业务的影响比较小. MHA就提 ...

  5. Json及Json字符串

    JSON(JavaScript Object Notation)是一种独立于开发语言的用于存储和交换文本数据的格式,JSON 语法是JavaScript 语法的子集. Json 可以保存数组格式和对象 ...

  6. CAP理论与MongoDB一致性、可用性的一些思考

    大约在五六年前,第一次接触到了当时已经是hot topic的NoSql.不过那个时候学的用的都是mysql,Nosql对于我而言还是新事物,并没有真正使用,只是不明觉厉.但是印象深刻的是这么一张图片( ...

  7. Unsupervised Learning and Text Mining of Emotion Terms Using R

    Unsupervised learning refers to data science approaches that involve learning without a prior knowle ...

  8. CodeForces 544C (Writing Code)(dp,完全背包)

    题意:有n个程序员,要协作写完m行代码,最多出现b个bug,第i个程序员每写一行代码就会产生a[i]个bug,现在问,这n个人合作来写完这m行代码,有几种方案使得出的bug总数不超过b(题中要求总方案 ...

  9. 移动端页面以rem为单位设置字体大小不生效解决方法

    这个问题在前端H5页面开发可以说是一个老生常谈的问题了.由于以前所有遇到的问题以及解决方法都会以文档的形式记录在电脑里,而非github或者blog,所以现在才一点一滴的整理上来,就当是一个心路历程吧 ...

  10. webApi签名验证

    还是一如既往先上结构图如下: 上一讲说明了redis,也谢谢心态的建议.这里经过改进后的redis的地址 当然这里是加密了的,具体实现如下图: 这里提供的解密. 先把加密解密的帮助类放上来. usin ...