Intent

2017/3/3 14:52 下午 posted in  Android  

基本用例:

  1. 启动Activity startActivity()、startActivityForResult() + onActivityResult()
  2. 启动服务 startService()、bindService()
  3. 传递广播
    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

闹钟

  1. 创建闹钟
  2. 创建定时器
  3. 显示所有闹铃

日历

  1. 添加日历事件

相机

  1. 拍摄照片或视频并将其返回
  2. 以静态图像模式启动相机应用
  3. 以视频模式启动相机应用

联系人/人员应用

  1. 选择联系人
  2. 选择特定联系人数据
  3. 查看联系人
  4. 编辑现有联系人
  5. 插入联系人

电子邮件

  1. 撰写带有可选附件的电子邮件

文件存储

  1. 检索特定类型的文件
  2. 打开特定类型的文件?

本地操作

  1. 叫车

地图

  1. 显示地图上的位置

音乐或视频

  1. 播放媒体文件
  2. 基于搜索查询播放音乐

新笔记

  1. 创建笔记

电话

  1. 发起电话,ACTION_DIAL、ACTION_CALL(需CALL_PHONE权限)

搜索

  1. 使用特定应用搜索
  2. 执行网页搜索

设置

  1. 打开特定设置部分

发送短信

  1. 撰写带附件的短信/彩信

网络浏览器

  1. 加载网址
    提示:如果您的 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

参考

Intent 和 Intent 过滤器
通用 Intent