Android Intent 对象详解

                                               Android Intent 对象详解

 

一 . Intent 介绍与分类

        Intent 可以翻译为 “ 意图 ”,也就是说 Intent 封装了 Android 应用程序需要启动某个组件的 “ 意图 ” 。Intent 是 Android 程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。其中,Intent 一般可被用于启动 Activity 、Service 、BroadcastReceiver 等场景。

        Intent 对象大致包含 Component 、Action 、Category 、Extra 和 Flag 这7种属性,其中 Component 用于明确指定需要启动的目标组件,而 Extra 则用于 “ 携带 ” 需要交换的数据。其中,根据是否明确指出将要启动哪个组件来把 Intent 分为两种类型:显式 Intent 和 隐式 Intent 。所谓的显示 Intent  就是指定了 Component 属性;而没有指定 Component 属性的 Intent 就称为隐式 Intent 。

 

二 . 显式 Intent 的简介和使用

         Intent 的 Component 属性需要接受一个 ComponentName 对象,ComponentName 对象包含如下几个构造器:

1)ComponentName ( String  pkg , String cls ) : 创建 pkg 所在包下的 cls 类所对应的组件。

2)ComponentName ( Context pkg , String cls ) :创建 pkg 所对应的包下的 cls 类所对应的组件。

3)ComponentName ( Content pkg ,Class <?> cls ) :创建 pkg 所对应的包下的 cls 类对应的组件。

        从上面的构造器中,可以说明创建一个 ComponentName 需要指定包名和类名,这就可以唯一确定一个组件类,这样应用程序就可以根据给定的组件类去启动特定的组件。

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

1)setClass ( Context packageContext , Class <?> cls ) : 设置该 Intent 将要启动的组件对应的类。

2)setClassName ( Context packageContext , String className ) : 设置该 Intent 将要启动的组件对应的类名。

3)setClassName ( String packageName , String className ) : 设置该 Intent 将要启动的组件对应的类名。

      下面通过代码来演示如何通过使用显式 Intent ( 即明确指定 Component 属性 ) 来启动另一个 Activity 。该程序的界面布局很简单,界面中只有一个按钮,用于单击按钮就会启动第二个 Activity ,如下所示:

 

实际上,上面的代码完全可以简化为我们平时最常用的形式,简化后的代码如下:

 

        首先创建出一个 Intent ,传入 MainActivity . this 作为上下文,传入secondActivity . class 作为目标组件,这样就明确指定了我们的 “ 意图 ”,即在MainActivity 这个活动的基础上打开 SecondActivity 这个活动。然后通过 startActivity ( ) ,方法来执行这个 Intent 。运行程序,在 MainActivity 的界面点击一下按钮,结果如下图所示:

     

 

三 . 隐式 Intent 简介和使用

前面也说了,隐式的 Intent 就是没有指定 Component 属性的 Intent ,也就是,在程序里没有清楚地指定需要启动哪个组件,而是通过一种含蓄的表达方式来指出需要启动的组件。这种含蓄的表达,需要使用一系列更为抽象的 Action 和 Category 等信息,然后提交给系统,让系统去分析这个 Intent ,并找出合适的组件去启动。

 

3 .1 Action 、Category 属性和 intent-filter 配置 

Intent 的 Action 和 Category 属性都是一个普通的字符串,其中 Action 代表该 Intent 所要完成的抽象的动作,而 Category 则用于给 Action 增加额外的附加类别信息,通常情况下,Action 属性会和 Category 属性同时使用。

Action 要完成的只是一个抽象的动作,这个动作具体由哪个组件(或许是 Activity ,或者是 BroadcastReceiver )来完成,Action 这个字符串本身并不管。比如:Android 提供的标准 Action —— Intent . ACTION_VIEW ,它只表示一个抽象的查看操作,但具体查看什么、启动哪个 Activity 来查看,Intent . ACTION_VIEW 并不知道,那到底谁知道呢?这就要查看 ActivityManifest . xml 中 < activity > 标签下配置  < intent-filter > 的配置信息了,只要某个 Activity 的  < intent-filter > 配置中包含了该 ACTION_VIEW ,该 Activity 就有可能被启动。

< intent-filter > 元素是 AndroidManifest . xml 文件中 < activity > 元素的子元素,它用于为应用程序配置 Activity ,< activity > 的 < intent-filter > 子元素则用于配置该 Activity 能有响应的 Intent 。

< intent-filter > 元素里通常可包含如下子元素:

  • 0 ~ N 个 < action > 子元素。

  • 0 ~ N 个 < category > 子元素。

  • 0 ~ 1 个 < data > 子元素。

< action > 、< category > 子元素的配置也很简单,它们都可指定 android :name 属性,该属性的值就是一个普通的字符串。

当 < activity > 元素里的 < intent-filter > 子元素里包含多个 < action > 子元素( 也就是指定了多个字符串 )时,就表明该 Activity 能响应 Action 属性值为其中任意一个字符串的 Intent 。

下面通过一个例子来示范 Action 熟悉的作用,代码和上面显式 Intent 中的代码基本相同,只不过这次不使用 “ 硬编码 ” 的方式指定要跳转的目标 Activity ,而是使用 隐式 Intent 这种含蓄的表达方式,为 Intent 指定 Action 属性。这里只给出关键的代码,界面里只有一个按钮,如下所示:

 

这里我们使用了 Intent 中的另一个构造函数,直接将 Action 的字符串传了进去,表明我们想要启动能够响应 com . bignerdranch . android . ACTION_DEMO 这个 Action 活动。

下面是被启动的 Activity 的完整配置,也就是在AndroidManifest . xml 中配置。

 

运行程序,确实和使用显示 Intent 中的结果一样,一样跳转到了 SecondActivity 页面。如下所示:

需要指出的是,一个 Intent 对象最多只能包含一个 Action 属性,程序可调用 Intent 的 startAction ( String str ) 方法来设置 Action 属性值;但一个 Intent 对象可以包含多个 Category 属性,程序可以调用 Intent 的 addCategroy ( String str ) 方法来为 Intent 添加 Category 属性。当程序创建 Intent 时,该 Intent 默认启动 Category 属性值为 Intent . CATEGORY_DEFAULT 常量(常量值为 android . intent . category .DEFAULT )的组件。

上面的程序中虽然为指定目标的 Intent 的 Category 属性,也就是在创建 Intent 的时候,没有使用 addCategroy ( String str ) 方法来为 Intent 添加 Category 属性,程序也能够运行,这是因为 android . intent . category . DEFAULT 是一种默认的 Category ,在调用 startActivity ( ) 方法的时候会自动将这个 Category 添加到 Intent 中 。

下面通过代码来示范如何添加 Category 属性值,例子还是和上面的一样,只是稍微修改一下,代码如下:

 

下面是被启动的 Activity 的完整配置,也就是在AndroidManifest . xml 中配置。

 

运行程序,一样跳转到了 SecondActivity 页面。如下所示:

 

 

3 . 2  指定 Action 、Category 属性调用系统 Activity  

在权限允许的情况下,Intent 还可以启动 Android 系统的其他应用的程序组件,而且 Android 内部也提供了大量标准的 Action 、Category 常量,其中用于启动 Activity 的标准 Action 常量及对应的字符串如下表:

启动 Activity 的标准 Action
           Action 常量                         对应字符串           简单说明
ACTION_MAINandroid . intent . action . MAIN应用程序入口
ACTION_VIEWandroid . intent . action . VIEW显示指定数据
ACTION_ATTACH_DATAandroid . intent . action . ATTACH_DATA指定某块数据将被附加到其他地方
ACTION_EDITandroid . intent . action . EDIT编辑指定数据
ACTION_PICKandroid . intent . action . PICK从列表中选择某项,并返回所选数据
ACTION_CHOOSERandroid . intent . action . CHOOSER选择一个 Activity 选择器
ACTION_GET_CONTENTandroid . intent . action . GET_CONTENT让用户选择数据,并返回所选数据
ACTION_DIALandroid . intent . action . DIAL显示拨号面板
ACTION_CALLandroid . intent . action . CALL直接向指定用户打电话
ACTION_SENDandroid . intent . action . SEND向其他人发送数据
ACTION_SENDTOandroid . intent . action . SENDTO向其他人发送消息
ACTION_ANSWERandroid . intent . action . ANSWER应答电话
ACTION_INSERTandroid . intent . action . INSERT插入数据
ACTION_DELETEandroid . intent . action . DELETE删除数据
ACTION_RUNandroid . intent . action . RUN运行数据
ACTION_SYNCandroid . intent . action . SYNC执行数据同步
ACTION_PICK_ACTIVITYandroid . intent . action . PICK . ACTIVITY用于选择 Activity 
ACTION_SEARCHandroid . intent . action . SEARCH执行搜索
ACTION_WEB_SEARCHandroid . intent . action . WEB_SEARCH执行 Web 搜索
ACTION_FACTORY_TESTandroid . intent . action . FACTORY_TEST工厂测试的入口点

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标准 Category 常量及对应的字符串如下表:

标准 Category
Category 常量对应字符串简单说明
CATEGORY_DEFAULTandroid . intent . category . DEFAULT默认的 Category
CATEGORY_BROWSABLEandroid . intent . category . BROWSABLE指定该 Activity 能被浏览器安全调用
CATEGORY_TABandroid . intent . category . TAB指定 Activity 作为 TabActivity 的 Tab 页
CATEGORY_LAUNCHERandroid . intent . category . LAUNCHERActivity 显示顶级程序列表中
CATEGORY_INFOandroid . intent . category . INFO用于提供包信息
CATEGORY_HOMEandroid . intent . category . HOME设置该 Activity 随系统启动而运行
CATEGORY_PREFERENCEandroid . intent . category . PREFERENCE该 Activity 是参数面板
CATEGORY_TESTandroid . intent . category . TEST该 Activity 是一个测试
CATEGORY_CAR_DOCKandroid . intent . category . CAR_DOCK指定手机被插入汽车底座(硬件)时运行该 Activity 
CATEGORY_DESK_DOCKandroid . intent . category . DESK_DOCK指定手机被插入汽车底座(硬件)时运行该 Activity 
CATEGORY_CAR_MODEandroid . intent . category . CAR_MODE设置该 Activity 可在车载环境下使用

 

 

 

 

 

 

 

 

 

 

 

 

 

下面通过两个例子来示范 Intent 系统 Action 、系统 Category 的用法。

实例一:代码还是和上面的同一个模版,首先指定了 Intent 的 Action 是 Intent . ACTION_VIEW ,这是一个 Android 系统内置的动作,其常量值为 android . intent . action . VIEW 。然后通过 Uri.parse ( ) 方法,将一个网址字符串解析程一个 Uri 对象,在调用 Intent 的 setData ( ) 方法将这个 Uri 对象传递出去。代码如下:

 

重新运行程序,在界面点击按钮就可以看到打开了系统浏览器,如下所示:

 

实例二:代码还是在上面的基础上修改,首先指定了 Intent 的 Action 是 Intent . ACTION_DIAL ,这又是一个 Android 系统的内置动作。然后在 data部分指定了协议是 tel ,号码是 10086 。显示代码如下所示:

 

3 . 3 Data 、Type 属性和 intent-filter 配置

Data 属性通常用于向 Action 属性提供操作的数据。Data 属性接受一个 Uri 对象,一个 Uri 对象通常通过如下形式的字符串来表示:

content : // com . android . contacts / contacts / 1

tel : 123

Uri 字符串总满足如下格式:

scheme : // host : port / path

例如上面给出的 content : // com . android . contacts / contacts / 1 ,其中 content 是 scheme 部分,com . android . contacts 是host 部分,port 部分被省略了,/ contacts / 1 是 path 部分。

Type 属性用于指定该 Data 所指定 Uri 对应的 MIME 类型,这种 MIME 类型可以是任何自定义的 MIME 类型,只要符合 abc / xyz 格式的字符串即可。

Data 属性与 Type 属性的关系比较微妙,这两个属性会相互覆盖,例如:

  • 如果为 Intent 先设置 Data 属性,后设置 Type 属性,那么 Type 属性将会覆盖 Data 属性。

  • 如果为 Intent 先设置 Type 属性,后设置 Data 属性,那么 Data 属性将会覆盖 Type 属性。

  • 如果希望 Intent 既有 Data 属性又有 Type 属性 ,应该调用 Intent 的 setDataAndType ( ) 方法。

在 AndroidManifest . xml 文件中为组件声明 Data 和 Type 属性都通过 < data > 元素,< data > 元素的格式如下:

<data
    android:host=""
    android:mimeType=""
    android:path=""
    android:pathPrefix=""
    android:port=""
    android:scheme=""
    android:sspPattern=""/>

上面的 < data > 元素支持如下属性:

  • mimeTyp : 用于声明该组件所能匹配的 Intent 的 Type 属性。

  • scheme :用于声明该组件所能匹配的 Intent 的 Data 属性的 scheme 部分。

  • host :用于声明该组件所能匹配的 Intent 的 Data 属性的 host 部分。

  • port :用于声明该组件所能匹配的 Intent 的 Data 属性的 port 部分。

  • path :用于声明该组件所能匹配的 Intent 的 Data 属性的 path 部分。

  • pathPrefix :用于声明该组件所能匹配的 Intent 的 Data 属性的 path 前缀。

  • pathPattern :用于声明该组件所能匹配的 Intent 的 Data 属性的 path 字符串模版。

Intent 的 Type 属性也用于指定该 Intent 的要求,必须对应组件中 < intent-filter > 元素中 < data > 子元素的 mimeType 属性与此相同,才能启动该组件。

Intent 的 Data 属性则略有差异,在为 Intent 指定 Data 属性时,Data 的属性的 Uri 对象实际上可分为 scheme 、host 、port 和 path 部分,此时并不要求其启动组件的 < intent-filter > 中 < data > 子元素的 android : scheme 、android : host 、android : port  、android : path 完全满足。

Data 属性的匹配过程如下:

  • 如果目标组件的 < data > 子元素只指定了 android : scheme 属性,那么只要 Intent 的 Data 属性的 scheme 部分与 android  : scheme 属性值相同,即可启动该组件。

  • 如果目标组件的 < data > 子元素只指定了 android : scheme 、android : host 属性,那么只要 Intent 的 Data 属性的 scheme 、host部分与 android  : scheme 、android : host 属性值相同,即可启动该组件。

  • 如果目标组件的 < data > 子元素只指定了 android : scheme 、android : host 、android : port  属性,那么只要 Intent 的 Data 属性的 scheme 、host 、port 部分与 android  : scheme 、android : host 、android : port  属性值相同,即可启动该组件。

下面通过五个例子进一步了解 Data 属性的匹配规则,下面只给出关键的代码,也就是只给出 < data > 子元素的配置,代码如下:

实例一:

 

实例二:

 

实例三:

 

实例四:

 

实例五:

 

下面是第一个Activity 的方法:

 

分析:

比较上面 Intent 的 Data 属性只有 scheme :demo 值相同  ,所以只能启动实例一。

 

下面是第二个 Activity 的方法:

 

分析:

比较上面 Intent 的 Data 属性,有 scheme : demo ,所以能启动实例一;

并且 host : intent .data , port :8888 属性值相同 ,所以也能启动实例二。

 

下面是第三个 Activity 的方法:

 

分析:

比较上面 Intent 的 Data 属性,有scheme : demo ,所以能启动实例一;

且 host : www . intent . data ; path : /mypath ,所以能启动实例三。

 

下面是第四个 Activity 的方法:

 

分析:

比较上面 Intent 的 Data 的属性,有scheme : demo ,所以能启动实例一;

并且 host : intent .data , port :8888 属性值相同 ,所以也能启动实例二;

并且 host : www . intent . data ; path : /mypath ,所以能启动实例三。

并且 host : www . intent . data ; port :8888 ;path : /mypath ,所以能启动实例四。

 

下面是第五个 Activity 的方法:

 

分析:

上面的 Intent 不仅指定了 Data 属性,还指定了 Type 属性,此时符合条件的只有实例五了。

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值