Intent对象详解

定义:Intent封装着Android程序需要启动某个组件的“意图”,不仅如此,Intent还是应用程序组件之间通信的媒介。

一、Intent的属性和intent-filter配置

Compenent属性:

  >>CompenentName(String pkg,String cls):

  >>CompenentName(Context pkg,String cls):

  >>CompenentName(StriContext ng pkg,Class<?> cls):统一都是创建pkg所对应的包下的cls类所对应的组件

  intent.setComponent(comp);

 

除此之外Intent还包含了如下三个方法

  >>setClass(Context pkgContext ,Class<?> cls):设置Intent要启动对应的类;

  >>setClassName(Context pkgContext ,String className)设置要启动组件对应的类名

  >>setClassName(Context pkgName ,String className)设置要启动组件对应的类名

 

其实Intent已经提供了一个简化的构造器:

  Intent intent = new Intent(Activity.this,SecondActivity.class);

对于向这三种组件发送intent有不同的机制:

  • 使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
  • 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
  • 将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver。

二、Intent的相关属性:

Intent由以下各个组成部分:

  • component(组件):目的组件
  • action(动作):用来表现意图的行动
  • category(类别):用来表现动作的类别
  • data(数据):表示与动作要操纵的数据
  • type(数据类型):对于data范例的描写
  • extras(扩展信息):扩展信息
  • Flags(标志位):期望这个意图的运行模式
  • Intent类型分为显式Intent(直接类型)、隐式Intent(间接类型)。官方建议使用隐式Intent。上述属性中,component属性为直接类型,其他均为间接类型。

相比与显式Intent,隐式Intnet则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。

Activity 中 Intent Filter 的匹配过程 :

058457504768

1、component(组件):目的组件

Component属性明确指定Intent的目标组件的类名称。(属于直接Intent),如果 component这个属性有指定的话,将直接使用它指定的组件。指定了这个属性以后,Intent的其它所有属性都是可选的。

例如,启动第二个Activity时,我们可以这样来写:

button1.setOnClickListener(new OnClickListener() {

  @Override
  public void onClick(View v) {
    //创建一个意图对象
    Intent intent = new Intent();
    //创建组件,通过组件来响应
    ComponentName component = new ComponentName(MainActivity.this, SecondActivity.class);
    intent.setComponent(component);
    startActivity(intent);
  }

});

  

2、Action(动作):用来表现意图的行动

  当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写” 一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。

  Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 <intent-filter >节点指定一个 Action列表用于标识 Activity 所能接受的“动作”。

3、category(类别):用来表现动作的类别

Category属性也是作为<intent-filter>子元素来声明的。例如:

<intent-filter>
  <action android:name="com.vince.intent.MY_ACTION"></action>
  <category android:name="com.vince.intent.MY_CATEGORY"></category>
  <category android:name="android.intent.category.DEFAULT"></category>
</intent-filter> 

 

Action 和category通常是放在一起用的,所以这里一起介绍一下。我们来先来举一个例子:

新建一个工程文件smyh006_Intent01,在默认文件的基础之上,新建文件SecondActicity.java和activity_second.xml。

紧接着,我们要到清单文件中进行注册,打开AndroidManifest.xml,添加SecondActivity的action和category的过滤器:

<activity
  android:name=".SecondActivity">
  <intent-filter>
    <action android:name="com.example.smyh006intent01.MY_ACTION"/>
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

 

上方代码,表示SecondActicity可以匹配第4行的MY_ACTION这个动作,此时,如果在其他的Acticity通过这个action的条件来查找,那SecondActicity就具备了这个条件。类似于相亲时,我要求对方有哪些条件,然后对方这个SecondActicity恰巧满足了这个条件(够通俗了吧)。

注:如果没有指定的category,则必须使用默认的DEFAULT(即上方第5行代码)。

也就是说:只有<action>和<category>中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应Intent。如果使用的是DEFAULT这种默认的category,在稍后调用startActivity()方法的时候会自动将这个category添加到Intent中。

现在来修改MainActivity.java中按钮的点击事件,代码如下:

button1.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    //启动另一个Activity,(通过action属性进行查找)
    Intent intent = new Intent();
    //设置动作(实际action属性就是一个字符串标记而已)
    intent.setAction("com.example.smyh006intent01.MY_ACTION"); //方法:Intent android.content.Intent.setAction(String action)
    startActivity(intent);
  }
});

上方代码中,也可以换成下面这种简洁的方式:
button1.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    //启动另一个Activity,(通过action属性进行查找)
    Intent intent = new Intent("com.example.smyh006intent01.MY_ACTION");//方法: android.content.Intent.Intent(String action)
    startActivity(intent);
  }
});

 

上方第5行代码:在这个Intent中,我并没有指定具体哪一个Activity,我只是指定了一个action的常量。所以说,隐式Intent的作用就表现的淋漓尽致了。此时,点击MainActicity中的按钮,就会跳到SecondActicity中去。

上述情况只有SecondActicity匹配成功。如果有多个组件匹配成功,就会以对话框列表的方式让用户进行选择。我们来详细介绍一下:

我们新建文件ThirdActicity.java和activity_third.xml,然后在清单文件AndroidManifest.xml中添加ThirdActivity的action和category的过滤器:

<activity
  android:name=".ThirdActivity">
  <intent-filter>
    <action android:name="com.example.smyh006intent01.MY_ACTION"/>
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

 

此时,运行程序,当点击MainActivity中的按钮时,弹出如下界面:

105265326026

相信大家看到了这个界面,应该就一目了然了。于是我们可以做出如下总结:

在自定义动作时,使用activity组件时,必须添加一个默认的类别

具体的实现为:

<intent-filter>
       <action android:name="com.example.action.MY_ACTION"/>
       <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

 

如果有多个组件被匹配成功,就会以对话框列表的方式让用户进行选择。

每个Intent中只能指定一个action,但却能指定多个category;类别越多,动作越具体,意图越明确(类似于相亲时,给对方提了很多要求)。

目前我们的Intent中只有一个默认的category,现在可以通过intent.addCategory()方法来实现。修改MainActivity中按钮的点击事件,代码如下:

 

我们可以总结如下:

  • 当Intent匹配成功的组件有多个时,显示优先级高的组件,如果优先级相同,显示列表让用户自己选择
  • 优先级从-1000至1000,并且其中一个必须为负的才有效

注:系统默认的浏览器并没有做出优先级声明,其优先级默认为正数。

优先级的配置如下:

在清单文件中修改对SecondAcivity的声明,即增加一行代码,通过来android:priority设置优先级,如下:

 

1 <activity 2 android:name=".SecondActivity"> 3 <intent-filter android:priority="-1"> 4 <action android:name="android.intent.action.VIEW" /> 5 <category android:name="android.intent.category.DEFAULT" /> 6 <data android:scheme="http" android:host="www.baidu.com"/> 7 </intent-filter> 8 </activity>

注:

Data属性的声明中要指定访问数据的Uri和MIME类型。可以在<data>元素中通过一些属性来设置:

android:scheme、android:path、android:port、android:mimeType、android:host等,通过这些属性来对应一个典型的Uri格式scheme://host:port/path。例如:http://www.google.com。

5、type(数据类型):对于data范例的描写

如果Intent对象中既包含Uri又包含Type,那么,在<intent-filter>中也必须二者都包含才能通过测试。

Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。

data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果想要两个属性同时设置,要使用Intent.setDataAndType()方法。

【任务】:data+type属性的使用 【实例】:播放指定路径的mp3文件。

具体如下:

新建工程文件smyh006_Intent02,MainActivity.java中按钮监听事件部分的代码如下:

copycode

copycode

1 button.setOnClickListener(new OnClickListener(){ 2 @Override 3 public void onClick(View v) { 4 Intent intent = new Intent(); 5 intent.setAction(Intent.ACTION_VIEW); 6 Uri data = Uri.parse("file:///storage/sdcard0/平凡之路.mp3"); 7 //设置data+type属性 8 intent.setDataAndType(data, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type) 9 startActivity(intent); 10 } 11 });

copycode

copycode

代码解释:

第6行:"file://"表示查找文件,后面再加上我的小米手机存储卡的路径:/storage/sdcard0,再加上具体歌曲的路径。

第8行:设置data+type属性  

运行后,当点击按钮时,效果如下:

115527977932

上方界面中,使用的是小米系统默认的音乐播放器。

6、extras(扩展信息):扩展信息

是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个

动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

7、Flags(标志位):期望这个意图的运行模式

一个程序启动后系统会为这个程序分配一个task供其使用,另外同一个task里面可以拥有不同应用程序的activity。那么,同一个程序能不能拥有多个task?这就涉及到加载activity的启动模式,这个需要单独讲一下。

注:android中一组逻辑上在一起的activity被叫做task,自己认为可以理解成一个activity堆栈。

一些常用的Intent:

Uri

Action

功能

geo:latitude,longitude

Intent.ACTION_VIEW

打开地图应用程序并显示指定的经纬度

geo:0,0?q=street+address

Intent.ACTION_VIEW

打开地图应用程序并显示指定的地址

http://web_address

Intent.ACTION_VIEW

打开浏览器程序并显示指定的URL

https://web_address

Intent.ACTION_VIEW

打开浏览器程序并显示指定的URL

tel:phone_number

Intent.ACTION_CALL

打开电话应用程序并拨打指定的电话号码

tel:phone_number

Intent.ACTION_DIAL

打开电话应用程序并拨下指定的电话号码

voicemail:

Intent.ACTION_DIAL

打开电话应用程序并拨下指定语音邮箱的电话号码

plain_text

Intent.ACTION_WEB_SEARCH

打开浏览器程序并使用Google搜索引擎搜索

活动:

Intent

说明

Action

CALL_ACTION

拨打电话,被呼叫的联系人在数据中指定。

android.intent.action.CALL

EMERGENCY_DIAL_ACTION

拨打紧急电话号码。

android.intent.action.EMERGENCY_DIAL

DIAL_ACTION

拨打数据中指定的电话号码。

android.intent.action.DIAL

ANSWER_ACTION

处理拨入的电话。

android.intent.action.ANSWER

DELETE_ACTION

从容器中删除给定的数据。

android.intent.action.DELETE

PICK_ACTION

从数据中选择一个项目 (item),将被选中的项目返回。

android.intent.action.PICK

DEFAULT_ACTION

和 VIEW_ACTION 相同,是在数据上执行的标准动作。

android.intent.action.VIEW

LOGIN_ACTION

获取登录凭证。

android.intent.action.LOGIN

ALL_APPS_ACTION

列举所有可用的应用。

android.intent.action.ALL_APPS

CLEAR_CREDENTIALS_ACTION

清除登陆凭证 (credential)。

android.intent.action.CLEAR_CREDENTIALS

GET_CONTENT_ACTION

让用户选择数据并返回。

android.intent.action.GET_CONTENT

EDIT_ACTION

为制定的数据显示可编辑界面。

android.intent.action.EDIT

BUG_REPORT_ACTION

显示 activity 报告错误。

android.intent.action.BUG_REPORT

SETTINGS_ACTION

显示系统设置。输入:无。

android.intent.action.SETTINGS

WALLPAPER_SETTINGS_ACTION

显示选择墙纸的设置界面。输入:无。

android.intent.action.WALLPAPER_SETTINGS

SENDTO_ACTION

向 data 指定的接收者发送一个消息。

android.intent.action.SENDTO

VIEW_ACTION

向用户显示数据。

android.intent.action.VIEW

PICK_ACTIVITY_ACTION

选择一个 activity,返回被选择的 activity 的类(名)。

android.intent.action.PICK_ACTIVITY

RUN_ACTION

运行数据(指定的应用),无论它(应用)是什么。

android.intent.action.RUN

INSERT_ACTION

在容器中插入一个空项 (item)。

android.intent.action.INSERT

ADD_SHORTCUT_ACTION

在系统中添加一个快捷方式。.

android.intent.action.ADD_SHORTCUT

WEB_SEARCH_ACTION

执行 web 搜索。

android.intent.action.WEB_SEARCH

SYNC_ACTION

执行数据同步。

android.intent.action.SYNC

MAIN_ACTION

作为主入口点启动,不需要数据。

android.intent.action.MAI

Intent

说明

Action

LABEL_EXTRA

大写字母开头的字符标签,和 ADD_SHORTCUT_ACTION 一起使用。

android.intent.extra.LABEL

INTENT_EXTRA

和 PICK_ACTIVITY_ACTION 一起使用时,说明用户选择的用来显示的 activity;和 ADD_SHORTCUT_ACTION 一起使用的时候,描述要添加的快捷方式。

android.intent.extra.INTENT

TEMPLATE_EXTRA

新记录的初始化模板。

android.intent.extra.TEMPLATE

Intent

说明

Action

XMPP_DISCONNECTED_ACTION

XMPP 连接已经被断开。

android.intent.action.XMPP_DI

XMPP_CONNECTED_ACTION

XMPP 连接已经被建立。

android.intent.action.XMPP_CONNECTED

BATTERY_CHANGED_ACTION

充电状态,或者电池的电量发生变化。

android.intent.action.BATTERY_CHANGED

TIME_TICK_ACTION

当前时间已经变化(正常的时间流逝)。

android.intent.action.TIME_TICK

DATA_ACTIVITY_STATE_CHANGED_ACTION

电话的数据活动(data activity)状态(即收发数据的状态)已经改变。

android.intent.action.DATA_ACTIVITY

DATA_CONNECTION_STATE_CHANGED_ACTION

电话的数据连接状态已经改变。

android.intent.action.DATA_STATE

MESSAGE_WAITING_STATE_CHANGED_ACTION

电话的消息等待(语音邮件)状态已经改变。

android.intent.action.MWI

SIGNAL_STRENGTH_CHANGED_ACTION

电话的信号强度已经改变。

android.intent.action.SIG_STR

SERVICE_STATE_CHANGED_ACTION

电话服务的状态已经改变。

android.intent.action.SERVICE_STATE

PHONE_STATE_CHANGED_ACTION

电话状态已经改变。

android.intent.action.PHONE_STATE

PROVIDER_CHANGED_ACTION

更新将要(真正)被安装。

android.intent.action.PROVIDER_CHANGED

FOTA_INSTALL_ACTION

更新已经被确认,马上就要开始安装。

android.server.checkin.FOTA_INSTALL

FOTA_READY_ACTION

更新已经被下载,可以开始安装。

android.server.checkin.FOTA_READY

FOTA_RESTART_ACTION

恢复已经停止的更新下载。

android.server.checkin.FOTA_RESTART

MEDIA_SCANNER_STARTED_ACTION

开始扫描介质的一个目录。

android.intent.action.MEDIA_SCANNER_STARTED

MEDIA_BAD_REMOVAL_ACTION

扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount)。

android.intent.action.MEDIA_BAD_REMOVAL

MEDIA_MOUNTED_ACTION

扩展介质被插入,而且已经被挂载。

android.intent.action.MEDIA_MOUNTED

MEDIA_REMOVED_ACTION

扩展介质被移除。

android.intent.action.MEDIA_REMOVED

MEDIA_UNMOUNTED_ACTION

扩展介质存在,但是还没有被挂载 (mount)。

android.intent.action.MEDIA_UNMOUNTED

MEDIA_SHARED_ACTION

扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享。

android.intent.action.MEDIA_SHARED

SCREEN_OFF_ACTION

屏幕被关闭。

android.intent.action.SCREEN_OFF

SCREEN_ON_ACTION

屏幕已经被打开。

android.intent.action.SCREEN_ON

FOTA_CANCEL_ACTION

取消所有被挂起的 (pending) 更新下载。

android.server.checkin.FOTA_CANCEL

DATE_CHANGED_ACTION

日期被改变。

android.intent.action.DATE_CHANGED

UMS_DISCONNECTED_ACTION

设备从 USB 大容量存储模式退出。

android.intent.action.UMS_DISCONNECTED

CONFIGURATION_CHANGED_ACTION

设备的配置信息已经改变,参见 Resources.Configuration.

android.intent.action.CONFIGURATION_CHANGED

UMS_CONNECTED_ACTION

设备进入 USB 大容量存储模式。

android.intent.action.UMS_CONNECTED

PACKAGE_REMOVED_ACTION

设备上删除了一个应用程序包。

android.intent.action.PACKAGE_REMOVED

PACKAGE_ADDED_ACTION

设备上新安装了一个应用程序包。

android.intent.action.PACKAGE_ADDED

NETWORK_TICKLE_RECEIVED_ACTION

设备收到了新的网络 “tickle” 通知。

android.intent.action.NETWORK_TICKLE_RECEIVED

TIME_CHANGED_ACTION

时间已经改变(重新设置)。

android.intent.action.TIME_SET

TIMEZONE_CHANGED_ACTION

时区已经改变。

android.intent.action.TIMEZONE_CHANGED

FOTA_UPDATE_ACTION

通过 OTA 下载并安装操作系统更新。

android.server.checkin.FOTA_UPDATE

STATISTICS_STATE_CHANGED_ACTION

统计信息服务的状态已经改变。

android.intent.action.STATISTICS_STATE_CHANGED

WALLPAPER_CHANGED_ACTION

系统的墙纸已经改变。

android.intent.action.WALLPAPER_CHANGED

PROVISIONING_CHECK_ACTION

要求 polling of provisioning service 下载最新的设置。

android.intent.action.PROVISIONING_CHECK

STATISTICS_REPORT_ACTION

要求 receivers 报告自己的统计信息。

android.intent.action.STATISTICS_REPORT

MEDIA_SCANNER_FINISHED_ACTION

已经扫描完介质的一个目录。

android.intent.action.MEDIA_SCANNER_FINISHED

MEDIABUTTON_ACTION

用户按下了“Media Button”。

android.intent.action.MEDIABUTTON

MEDIA_EJECT_ACTION

用户想要移除扩展介质(拔掉扩展卡)。

android.intent.action.MEDIA_EJECT

CALL_FORWARDING_STATE_CHANGED_ACTION

语音电话的呼叫转移状态已经改变。

android.intent.action.CFF

BOOT_COMPLETED_ACTION

在系统启动后,这个动作被广播一次(只有一次)。

android.intent.action.BOOT_COMPLETED

Intent

说明

Action

LAUNCHER_CATEGORY

Activity 应该被显示在顶级的 launcher 中。

android.intent.category.LAUNCHER

PREFERENCE_CATEGORY

activity是一个设置面板 (preference panel)。

android.intent.category.PREFERENCE

SAMPLE_CODE_CATEGORY

To be used as an sample code example (not part of the normal user experience).

android.intent.category.SAMPLE_CODE

FRAMEWORK_INSTRUMENTATION_TEST_CATEGORY

To be used as code under test for framework instrumentation tests.

android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST

SELECTED_ALTERNATIVE_CATEGORY

对于被用户选中的数据,activity 是它的一个可选操作。

android.intent.category.SELECTED_ALTERNATIVE

BROWSABLE_CATEGORY

能够被浏览器安全使用的 activities 必须支持这个类别。

android.intent.category.BROWSABLE

EMBED_CATEGORY

能够在上级(父)activity 中运行。

android.intent.category.EMBED

DEFAULT_CATEGORY

如果 activity 是对数据执行确省动作(点击, center press)的一个选项,需要设置这个类别。

android.intent.category.DEFAULT

DEVELOPMENT_PREFERENCE_CATEGORY

说明 activity 是一个设置面板 (development preference panel).

android.intent.category.DEVELOPMENT_PREFERENCE

ALTERNATIVE_CATEGORY

说明 activity 是用户正在浏览的数据的一个可选操作。

android.intent.category.ALTERNATIVE

UNIT_TEST_CATEGORY

应该被用作单元测试(通过 test harness 运行)。

android.intent.category.UNIT_TEST

GADGET_CATEGORY

这个 activity 可以被嵌入宿主 activity (activity that is hosting gadgets)。

android.intent.category.GADGET

WALLPAPER_CATEGORY

这个 activity 能过为设备设置墙纸。

android.intent.category.WALLPAPER

TAB_CATEGORY

这个 activity 应该在 TabActivity 中作为一个 tab 使用。

android.intent.category.TAB

HOME_CATEGORY

主屏幕 (activity),设备启动后显示的第一个 activity。

android.intent.category.HOME

TEST_CATEGORY

作为测试目的使用,不是正常的用户体验的一部分。

android.intent.category.TEST

标志

描述

MULTIPLE_TASK_LAUNCH

和 NEW_TASK_LAUNCH 联合使用,禁止将已有的任务改变为前景任务 (foreground)。

8 0x00000008

FORWARD_RESULT_LAUNCH

如果这个标记被设置,而且被一个已经存在的 activity 用来启动新的 activity,已有 activity 的回复目标 (reply target) 会被转移给新的 activity。

16 0x00000010

NEW_TASK_LAUNCH

设置以后,activity 将成为历史堆栈中的第一个新任务(栈顶)。

4 0x00000004

SINGLE_TOP_LAUNCH

设置以后,如果 activity 已经启动,而且位于历史堆栈的顶端,将不再启动(不重新启动) activity。

2 0x00000002

NO_HISTORY_LAUNCH

设置以后,新的 activity 不会被保存在历史堆栈中。

1 0x00000001

posted @ 2018-08-03 10:46  vvning  阅读(2803)  评论(0编辑  收藏  举报