基本用例:
- 启动Activity startActivity()、startActivityForResult() + onActivityResult()
- 启动服务 startService()、bindService()
传递广播
sendBroadcast()、sendOrderedBroadcast()、sendStickyBroadcast()
Intent类型
- 显式Intent。 按完全限定类名指定要启动的组件,通常在自己的应用中使用。 如果没有在清单文件中为Activity声明任何Intent过滤器,则其只能通过显式Intent启动。
- 隐式Intent。 不指定特定的组件,而是声明要执行的常规操作。 Android系统通过将Intent内容与设备上其他应用的清单文件中声明的Intent过滤器进行比较,找到匹配的组件。
注:启动Service时,为确保安全性,应始终使用显式Intent,且不要为Service声明Intent过滤器。因为使用隐式Intent不能确定哪些Service将响应Intent,且用户无法看到哪些Service已启动。从Android5.0(API 21)起,通过隐式Intent调用bindService()会引发异常。
构建Intent
Intent包含如下信息:
- 组件名称 若不提供,则Intent为隐式的。ComponentName对象,可使用setComponent()、setClass()、setClassName()或Intent构造方法设置。
- 操作(Action) 使用Intent类或其他框架类定义的操作常量,也可使用自定义的操作,供Intent在自己的应用内使用。
- 数据(Data) 指定URI(包含独立的scheme、host、port、path属性)、MIME类型。设置数据URI,调用setData();设置MIME类型,调用setType();若同时设置2者,调用setDataAndType()。
- 类别(Category) 可设置任意数量的类别。例如CATEGORY_BROWSABLE、CATEGORY_LAUNCHER。可使用addCategory()指定类别。
Intent还可以携带不影响其如何解析为应用组件的信息:
- Extra 携带附加信息。putExtra(String key, 各种类型的value),或putExtras(Bundle bundle)。
- 标志(Flag) 指示系统如何启动Activity(如Activity属于哪个任务),启动之后如何处理(如Activity是否属于最近的Activity列表)。
隐式Intent
使用隐式Intent startActivity()时,需要先使用resolveActivity()判断是否有应用能够处理该Intent,如果结果为空,则不能继续使用该Intent。
示例:
// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
PackageManger提供了一套query...()方法来返回所有能够接受特定Intent的组件,还提供了一系列类似的resolve...()方法来确定响应Intent的最佳组件。这2种方法均不会激活组件,而只是列出能够响应的组件。如queryIntentActivities()、queryIntentServices()、queryIntentBroadcastReceivers()。
强制使用应用选择器
比如“共享”操作,每次都需要显示应用选择器,不应让用户设置默认选项。使用createChooser()创建Intent,并传递给startActivity()。
示例:
Intent sendIntent = 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 the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
接收隐式Intent
在清单文件中的相应组件(如activity)中添加intent-filter,可以使用action、data、category元素。
为了接收隐式Intent,必须在intent-filter中添加CATEGORY_DEFAULT类别。
一个应用组件可以包含多个intent-filter。
Activity必须在清单文件中声明Intent过滤器,但广播接收器的过滤器可以通过调用registerReceiver()动态注册,通过unregisterReceiver()注销该接收器。
如下,ACTION_MAIN和CATEGORY_LAUNCHER必须配对使用,Activity才会显示在应用启动器中。
<activity android:name="MainActivity">
<!-- This activity is the main entry, should appear in app launcher -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
PendingIntent
PendingIntent是Intent的包装器。主要是授权外部应用使用包含的Intent,就像是它从自己的应用进程中执行的一样。
主要用例:
- 通知 NotificationManager;
- 应用小部件;
- AlarmManager。
Intent设计为由特定类型的应用组件(Activity、Service、BroadcastReceiver)处理,所以创建PendingIntent时,需声明所需的组件类型:
- PendingIntent.getActivity();
- PendingIntent.getService();
- PendingIntent.getBroadcast()。
通用Intent
闹钟
- 创建闹钟
- 创建定时器
- 显示所有闹铃
日历
- 添加日历事件
相机
- 拍摄照片或视频并将其返回
- 以静态图像模式启动相机应用
- 以视频模式启动相机应用
联系人/人员应用
- 选择联系人
- 选择特定联系人数据
- 查看联系人
- 编辑现有联系人
- 插入联系人
电子邮件
- 撰写带有可选附件的电子邮件
文件存储
- 检索特定类型的文件
- 打开特定类型的文件?
本地操作
- 叫车
地图
- 显示地图上的位置
音乐或视频
- 播放媒体文件
- 基于搜索查询播放音乐
新笔记
- 创建笔记
电话
- 发起电话,ACTION_DIAL、ACTION_CALL(需CALL_PHONE权限)
搜索
- 使用特定应用搜索
- 执行网页搜索
设置
- 打开特定设置部分
发送短信
- 撰写带附件的短信/彩信
网络浏览器
- 加载网址
提示:如果您的 Android 应用提供与您的网站相似的功能,请为指向您的网站的 URL 加入一个 Intent 过滤器。 之后,如果用户安装了您的应用,点击电子邮件或其他网页中指向您的网站的链接时,将会打开您的 Android 应用而不是您的网页。
验证Intent
adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \
-e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
如:
adb shell am start -a android.intent.action.DIAL \
-d tel:555-5555 -n org.example.MyApp/.MyActivity