一、Intent的发送 启动activity 或 应用
建立隐式的Intent
Implicit intents并不声明要启动组件的具体类名,而是声明一个需要执行的action。这个action指定了我们想做的事情,例如查看,编辑,发送或者是获取一些东西。Intents通常会在发送action的同时附带一些数据,例如你想要查看的地址或者是你想要发送的邮件信息。数据的具体类型取决于我们想要创建的Intent,比如Uri或其他规定的数据类型,或者甚至也可能根本不需要数据。
下面是一些其他intent的例子:
查看地图:
查看网页:
至于另外一些需要extra数据的implicit intent,我们可以使用putExtra()方法来添加那些数据。 默认的,系统会根据Uri数据类型来决定需要哪些合适的MIME type。如果我们没有在intent中包含一个Uri, 则通常需要使用setType()方法来指定intent附带的数据类型。设置MIME type 是为了指定应该接受这个intent的activity。例如:
发送一个带附件的email:
创建一个日历事件:
Note:这个intent for Calendar的例子只使用于>=API Level 14。
Note:请尽可能的将Intent定义的更加确切。例如,如果想要使用ACTION_VIEW 的intent来显示一张图片,则还应该指定 MIME type 为image/*.这样能够阻止其他能够 "查看" 其他数据类型的app(比如一个地图app) 被这个intent叫起。
验证是否有App去接收这个Intent
尽管Android系统会确保每一个确定的intent会被系统内置的app(such as the Phone, Email, or Calendar app)之一接收,但是我们还是应该在触发一个intent之前做验证是否有App接受这个intent的步骤。
Caution: 如果触发了一个intent,而且没有任何一个app会去接收这个intent,则app会crash。
为了验证是否有合适的activity会响应这个intent,需要执行queryIntentActivities()来获取到能够接收这个intent的所有activity的list。若返回的List非空,那么我们才可以安全的使用这个intent。例如:
如果isIntentSafe为true, 那么至少有一个app可以响应这个intent。false则说明没有app可以handle这个intent。
Note:我们必须在第一次使用之前做这个检查,若是不可行,则应该关闭这个功能。如果知道某个确切的app能够handle这个intent,我们也可以向用户提供下载该app的链接。(see how to link to your product on Google Play).
使用Intent启动Activity
当创建好了intent并且设置好了extra数据后,通过执行startActivity() 将intent发送到系统。若系统确定了多个activity可以handle这个intent,它会显示出一个dialog,让用户选择启动哪个app。如果系统发现只有一个app可以handle这个intent,则系统将直接启动该app。
startActivity(intent);
显示分享App的选择界面
请注意,当以startActivity()的形式传递一个intent,并且有多个app可以handle时,用户可以在弹出dialog的时候选择默认启动的app(通过勾选dialog下面的选择框,如上图所示)。该功能对于用户有特殊偏好的时候非常有用(例如用户总是喜欢启动某个app来查看网页,总是喜欢启动某个camera来拍照)。
然而,如果用户希望每次都弹出选择界面,而且每次都不确定会选择哪个app启动,例如分享功能,用户选择分享到哪个app都是不确定的,这个时候,需要强制弹出选择的对话框。(这种情况下用户不能选择默认启动的app)。
为了显示chooser, 需要使用createChooser()来创建Intent
这样就列出了可以响应createChooser()中Intent的app,并且指定了标题。
二、接收Activity返回的结果
启动另外一个activity并不一定是单向的。我们也可以启动另外一个activity然后接受一个返回的result。为接受result,我们需要使用startActivityForResult(),而不是startActivity()。
当然,被启动的activity需要指定返回的result。它需要把这个result作为另外一个intent对象返回,我们的activity需要在onActivityResult()的回调方法里面去接收result。
Note:在执行startActivityForResult()时,可以使用explicit 或者 implicit 的intent。当启动另外一个位于的程序中的activity时,我们应该使用explicit intent来确保可以接收到期待的结果。
启动Activity
对于startActivityForResult() 方法中的intent与之前介绍的并无太大差异,不过是需要在这个方法里面多添加一个int类型的参数。
该integer参数称为"request code",用于标识请求。当我们接收到result Intent时,可从回调方法里面的参数去判断这个result是否是我们想要的。
例如,下面是一个启动activity来选择联系人的例子:
接收Result
当用户完成了启动之后activity操作之后,系统会调用我们activity中的onActivityResult() 回调方法。该方法有三个参数:
通过startActivityForResult()传递的request code。
第二个activity指定的result code。如果操作成功则是RESULT_OK,如果用户没有操作成功,而是直接点击回退或者其他什么原因,那么则是RESULT_CANCELED
包含了所返回result数据的intent。
例如,下面显示了如何处理pick a contact的result:
为正确处理这些result,我们必须了解那些result intent的格式。对于自己程序里面的返回result是比较简单的。Apps都会有一些自己的api来指定特定的数据。例如,People app (Contacts app on some older versions) 总是返回一个URI来指定选择的contact,Camera app 则是在data数据区返回一个 Bitmap (see the class aboutCapturing Photos).
读取联系人数据
上面的代码展示了如何获取联系人的返回结果,但没有说清楚如何从结果中读取数据,因为这需要更多关于content providers的知识。但如果想知道的话,下面是一段代码,展示如何从被选的联系人中读出电话号码。
Note:在Android 2.3 (API level 9)之前对Contacts Provider的请求(比如上面的代码),需要声明READ_CONTACTS权限(更多详见Security and Permissions)。但如果是Android 2.3以上的系统就不需要这么做。但这种临时权限也仅限于特定的请求,所以仍无法获取除返回的Intent以外的联系人信息,除非声明了READ_CONTACTS权限。
源地址:http://wiki.jikexueyuan.com/project/android-training-geek/intents-index.html