AndroidIntent和IntentFilter详解.docx

上传人:b****5 文档编号:6295371 上传时间:2023-01-05 格式:DOCX 页数:12 大小:24.56KB
下载 相关 举报
AndroidIntent和IntentFilter详解.docx_第1页
第1页 / 共12页
AndroidIntent和IntentFilter详解.docx_第2页
第2页 / 共12页
AndroidIntent和IntentFilter详解.docx_第3页
第3页 / 共12页
AndroidIntent和IntentFilter详解.docx_第4页
第4页 / 共12页
AndroidIntent和IntentFilter详解.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

AndroidIntent和IntentFilter详解.docx

《AndroidIntent和IntentFilter详解.docx》由会员分享,可在线阅读,更多相关《AndroidIntent和IntentFilter详解.docx(12页珍藏版)》请在冰豆网上搜索。

AndroidIntent和IntentFilter详解.docx

AndroidIntent和IntentFilter详解

AndroidIntent和IntentFilter详解

(一)

IntentsandIntentFilters

      IntentObjectsIntent对象

      IntentResolutionIntent解析

      Intentfilters

      FiltersandsecurityFilter和安全

      Commoncases常见情况

      Usingintentmatching使用intent匹配

      NotePadExample例子:

记事本

      IntentsandIntentFilters

      三种应用程序基本组件——activity,service和broadcastreceiver——是使用称为intent的消息来激活的。

Intent消息传递是一种组件间运行时绑定的机制.intent是Intent对象,它包含了需要做的操作的描述,或者,对于广播来说,包含了正在通知的消息内容.对于向这三种组件发送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()等广播方法,则它们被传给broadcastreceiver.

      在上述三种情况下,android系统会自己找到合适的activity,service,或者  broadcastreceivers来响应intent.三者的intent相互独立互不干扰.

      IntentObjectsIntent对象

      一个intent对象包含了接受该intent的组件的信息(例如需要的动作和该动作需要的数据)和android系统所需要的信息.具体的说:

      组件名称

      为一个ComponentName对象.它是目标组件的完整名(例如"com.example.project.app.FreneticActivity")和应用程序manifest文件设定的包名(例如"com.example.project")的组合.前者的包名部分和后者不一定一样.

组件名称是可选的.如果设定了的话,Intent对象会被传给指定的类的一个实例.如果不设定,则android使用其它信息来定位合适的目标.

      组件名称是使用setComponent(),setClass(),或  setClassName()来设定,使用getComponent()来获取.

      Action

      一个字符串,为请求的动作命名,或者,对于broadcastintent,发生的并且正在被报告的动作.例如:

常量

目标组件

动作

ACTION_CALL

activity

发起一个电话呼叫.

ACTION_EDIT

activity

显示数据给用户来编辑.

ACTION_MAIN

activity

将该activity作为一个task的第一个activity启动,不传入参数也不期望返回值.

ACTION_SYNC

activity

将设备上的数据和一个服务器同步.

ACTION_BATTERY_LOW

broadcastreceiver

发出电量不足的警告.

ACTION_HEADSET_PLUG

broadcastreceiver

一个耳机正被插入或者拔出.

ACTION_SCREEN_ON

broadcastreceiver

屏幕被点亮.

ACTION_TIMEZONE_CHANGED

broadcastreceiver

时区设置改变.

      你也可以定义自己的action字符串用来启动你的应用程序.自定义的action应该包含应用程序的包名.例如"com.example.project.SHOW_COLOR".

      action很大程度上决定了intent的另外部分的结构,就像一个方法名决定了它接受的参数和返回值一样.因此,最好给action一个最能反映其作用的名字.

      一个intent对象中的action是使用getAction()和setAction()来读写的.

AndroidIntent和IntentFilter详解

(二)

 Data

      需要操作的数据的URI和它的MIME(多用途互联网邮件扩展,MultipurposeInternetMailExtensions)类型.例如,如果action为ACTION_EDIT,那么Data将包含待编辑的数据URI.如果action为ACTION_CALL,Data将为tel:

电话号码的URI.如果action为ACTION_VIEW,则Data为http:

网络地址的URI.

      当将一个intent和一个组件相匹配时,除了URI外数据类型也很重要.例如,一个显示图片的程序不应该用来处理声音文件.

      数据类型常常可以从URI推断,特别是content:

URI,它表示该数据属于一个contentprovider.但数据类型也可以被intent对象显示声明.setData()方法设置URI,而setType()方法指定MIME类型,setDataAndType()设置数据URI和MIME类型.它们可以使用getData()和getType()来读取.

      Category

      一个字符串,包含了关于处理该intent的组件的种类的信息.一个intent对象可以有任意个category.intent类定义了许多category常数,例如:

常量

含义

CATEGORY_BROWSABLE

目标activity可以使用浏览器来显示-例如图片或电子邮件消息.

CATEGORY_GADGET

该activity可以被包含在另外一个装载小工具的activity中.

CATEGORY_HOME

该activity显示主屏幕,也就是用户按下Home键看到的界面.

CATEGORY_LAUNCHER

该activity可以作为一个任务的第一个activity,并且列在应用程序启动器中.

CATEGORY_PREFERENCE

该activity是一个选项面板.

      addCategory()方法为一个intent对象增加一个category,removeCategory删除一个category,getCategories()获取intent所有的category.

      Extras

      为键值对形式的附加信息.例如ACTION_TIMEZONE_CHANGED的intent有一个"time-zone"附加信息来指明新的时区,而ACTION_HEADSET_PLUG有一个"state"附加信息来指示耳机是被插入还是被拔出.

intent对象有一系列put...()和set...()方法来设定和获取附加信息.这些方法和Bundle对象很像.事实上附加信息可以使用putExtras()和getExtras()作为Bundle来读和写.

      Flags

      各种标志.很多标志指示android系统如何启动一个activity(例如该activity属于哪个任务)和启动后如何处理它(例如,它是否属于最近activity列表中).

      android系统和应用程序使用intent对象来送出系统广播和激活系统定义的组件.

      IntentResolutionIntent解析

      intent有两种:

     显式intent使用名字来指定目标组件.由于组件名称一般不会被其它开发者所熟知,这种intent一般用于应用程序内部消息--例如一个activity启动一个附属的service或者另一个activity.

      隐式intent不指定目标的名称.一般用于启动其它应用程序的组件.

      Android将显式intent发送给指定的类.intent对象中名字唯一决定接受intent的对象.对于隐式intent,android系统必须找到最合适的组件来处理它.它比较intent的内容和intentfilter.  intentfilter是组件的一个相关结构,表示其接受intent的能力.android系统根据intentfilter打开可以接受intent的组件.如果一个组件没有intentfilter,那么它只能接受显式intent.如果有,则能同时接受二者.当一个intent和intentfilter比较时,只考虑三个属性:

action,data,category.extra和flag在intent解析中没有用.

      Intentfilters

      activity,service和broadcastreceiver可以有多个intentfilter来告知系统它们能接受什么样的隐式intent.intentfilter的名字很形象:

它过滤掉不想接受的intent,留下想接受的intent.显式intent无视intentfilter.一个组件对能做的每件事有单独的filter.例如,记事本程序的NoteEditoractivity有两个filter--一个启动并显示一个特定的记录给用户查看或编辑,另一个启动一个空的记录给用户编辑.

      FiltersandsecurityFilter和安全

      一个intentfilter不一定安全可靠.一个应用程序可以让它的某个组件去接受隐式intent,但是它没法防止这个组件接受显示intent.其它的程序总是可以使用自定义的数据加上显式的程序名称来调用该组件.

      一个intentfilter是IntentFilter类的实例,但是它一般不出现在代码中,而是出现在androidManifest文件中,以的形式.(有一个例外是broadcastreceiver的intentfilter是使用Context.registerReceiver()来动态设定的,其intentfilter也是在代码中创建的.)

      一个filter有action,data,category等字段.一个隐式intent为了能被某个intentfilter接受,必须通过3个测试.一个intent为了被某个组件接受,则必须通过它所有的intentfilter中的一个.

    Action测试

java代码:

1.

2.

name="com.example.project.SHOW_CURRENT"/>

3.

name="com.example.project.SHOW_RECENT"/>

4.

name="com.example.project.SHOW_PENDING"/>

5....

6.

复制代码

AndroidIntent和IntentFilter详解(三)

 一个intent对象只能指定一个action,而一个intentfilter可以指定多个action.action列表不能为空,否则它将组织所有的intent.

      一个intent对象的action必须和intentfilter中的某一个action匹配,才能通过.如果intentfilter的action列表为空,则不通过.如果intent对象不指定action,并且intentfilter的action列表不为空,则通过.

      Category测试

java代码:

1.

2.

name="android.intent.category.DEFAULT"/>

3.

name="android.intent.category.BROWSABLE"/>

4.

      注意前面说到的对于action和category的常数是在代码中用的,而不是manifest文件中用的.例如,CATEGORY_BROWSABLE常数对应xml中的表示为"android.intent.category.BROWSABLE".

一个intent要通过category测试,那么该intent对象中的每个category都必须和filter中的某一个匹配.

理论上来说,一个intent对象如果没有指定category的话,它应该能通过任意的category测试.有一个例外:

android把所有的传给startActivity()的隐式intent看做至少有一个category:

"android.intent.category.DEFAULT".因此,想要接受隐式intent的activity必须在intentfilter中加入"android.intent.category.DEFAULT".

    Datatest

java代码:

1.

2.

mimeType="video/mpeg"android:

scheme="http".../>

3.

mimeType="audio/mpeg"android:

scheme="http".../>

4....

5.

      每个元素指定了一个URI和一个数据类型.URI每个部分为不同的属性--scheme,host,port,path:

scheme:

//host:

port/path

      例如,在如下的URI中:

content:

//com.example.project:

200/folder/subfolder/etc

      scheme为"content",host为"com.example.project",port为"200",path为"folder/subfolder/etc".host和port一起组成了URIauthority.如果host未指定,则port被忽略.

      这些属性都是可选的,但它们并非相互独立:

要使一个authority有意义,必须指定一个scheme.要使一个path有意义,必须指定一个scheme和一个authority.

      当intent对象中的URI和intentfilter中相比较时,它只和filter中定义了的部分比较.例如,如果filter中之定义了scheme,那么所有包含该scheme的URI的intent对象都通过测试.对于path来说,可以使用通配符来进行部分匹配.

元素的type属性指定了数据类型.它在filter中比在URI中更常见.intent对象和filter都可以使用"*"通配符作为子类型.例如"text/*""audio/*"表示所有的子类型都匹配.

      data测试的规则如下:

      一个不含uri也不含数据类型的intent对象只通过两者都不包含的filter.

      一个含uri但不含数据类型的intent对象(并且不能从uri推断数据类型的)只能通过这样的filter:

uri匹配,并且不指定类型.这种情况限于类似mailto:

和tel:

这样的不指定实际数据的uri.

      一个只包含数据类型但不包含URI的intent只通过这样的filter:

该filter只列出相同的数据类型,并且不指定uri.

      一个既包含uri又包含数据类型的intent对象只通过这样的filter:

intent对象的数据类型和filter中的一个类型匹配,intent对象的uri要么和filter的uri匹配,要么intent对象的uri为content:

或者file:

并且filter不指定uri.

      如果一个intent可以通过多于一个activity或者service的filter,那么用户可能会被询问需要启动哪一个.如果一个都没有的话,那么会抛出异常.

      Commoncases常见情况

      上述的最后一个规则(d)说明了组件通常可以从文件和contentprovider中获取数据.因此,它们的filter可以只列出数据类型不列scheme.这是个特殊情况.下列元素告诉android该组件可以从一个contentprovider取得图像数据并显示之:

java代码:

1.

mimeType="image/*"/>

    由于大部分可用的数据由contentprovider提供,指定数据类型但不指定uri的filter是最常见的情况.

    另外一个常见的配置是filter具有一个scheme和一个数据类型.例如,下列元素告诉android该component可以从网络获取图像数据并显示之:

java代码:

1.

scheme="http"android:

type="video/*"/>

    考虑用户点击一个网页时浏览器的动作.它首先试图显示这个数据(当做一个html页来处理).如果无法显示,则创建一个隐式intent,并启动一个可以处理它的activity.如果没有这样的activity,那么它请求下载管理器来下载该数据.然后它将数据置于一个contentprovider的控制之下,这样有很多activity(拥有只有数据类型的filter)可以处理这些数据.

      大部分应用程序还有一种方法来单独启动,不需要引用任何特定的数据.这些能启动应用程序的activity具有action为"android.intent.action.MAIN"的filter.如果它们需要在应用程序启动器中显示,它们必须指定"android.intent.category.LAUNCHER"的category.

java代码:

1.

2.

name="codeandroid.intent.action.MAIN"/>

3.

name="codeandroid.intent.category.LAUNCHER"/>

4.

复制代码

AndroidIntent和IntentFilter详解(四)

Usingintentmatching使用intent匹配

      intent和intentfilter相匹配,不仅为了寻找并启动一个目标组件,也是为了寻找设备上组件的信息.例如,android系统启动了应用程序启动器,该程序位于屏幕的顶层,显示了用户可以启动的程序,这是通过查找设备上所有的action为"android.intent.action.MAIN",category为"android.intent.category.LAUNCHER"的intentfilter所在的activity实现的.然后它显示了这些activity的图标和标题.类似的,它通过寻找"android.intent.category.HOME"的filter来定位主屏幕程序.

    应用程序可以用相同的方式来使用intent匹配.PackageManager有一组query...()方法来寻找接受某个特定intent的所有组件,还有一系列resolve...()方法来决定响应一个intent的最佳组件.例如,queryIntentActivities()返回一个activity列表,这些activity可以执行传入的intent.类似的还有queryIntentServices()和queryIntentBroadcastReceivers().

      NotePadExample例子:

记事本

      记事本示例程序让用户可以浏览一个笔记列表,查看,编辑,删除和增加笔记.这一节关注该程序定义的intentfilter.

      在其manifest文件中,记事本程序定义了三个activity,每个有至少一个intentfilter.它还定义了一个contentprovider来管理笔记数据.manifest文件如下:

java代码:

1.

android="

2.package="eoe.demo">

3.

icon="@drawable/app_notes"

4.android:

label="@string/app_name">

5.

6.

name="NotePadProvider"

7.android:

authorities="com.google.provider.NotePad"/>

8.

9.

name="NotesList"android:

label="@string/t

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学案例设计

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1