安卓意图过滤器 约束和mime什么Type干什么用啊

我有两个用于应用程序根活动的意图过滤器

一个过滤器用于从启动器图标启动应用程序,另一个过滤器用于在用户触摸NFC标签时启动活动.

我希望当用户从应用程序中的任何活動中按下HOME按钮时,下次他按下启动器图标或触摸NFC标签时,该应用程序必须恢复(每个应用程序都是这种情况).

但这是正在发生的事情:
当用户点击NFC標签时,将启动第一个活动.然后,他导航到其他活动.按HOME.再次点击NFC标签,启动第一个活动(MyActivity),并清除前一个堆栈.

当用户选择启动器图标,导航到其他活动,按HOME,然后再次按启动器图标时,MyActivity作为堆栈顶部的新活动启动. (现在,堆栈中有两个MyActivities).

您需要定义活动的启动方式.

一个应用程序的三个核心组件-活動服务和广播接收器是通过消息即意图(Intents)来激活的。Intent消息传送是相同或不同应用中组件运行时晚绑定的一种机制意图本身,一个意圖对象是一个包含被执行操作抽象描述的被动的数据结构-或者,对于广播而言是某件已经发生并被声明的事情的描述。存在不同的机淛来传送意图到每种组件中:

  • 一个意图对象是传递给或者来启动一个活动或者让一个存在的活动去做某些新的事情
  • 一个意图对象是传递給来发起一个服务或者递交新的指令给运行中的服务。类似的一个意图能被传递给 来在调用组件和一个目标服务之间建立连接。作为一個可选项它可以发起这个服务如果还没运行的话。
  • 传递给任意广播方法(例如,或者)的意图对象被传递给所有感兴趣的广播接收者许多種广播产生于系统代码。 

在每个例子里Android系统找到合适的活动,服务或者一组广播接收者来回应这个意图,必要时实例化它们这些消息传送系统没有重叠:广播意图仅被传递给广播接收者,永远不会给活动或者服务一个传送给startActivity()的意图是只会被传递给一个活动,永远不會给一个服务或广播接收者如此类推。

这篇文档以意图对象的描述开始然后描述Android映射意图到组件的规则-如何解决哪个组件应该接收一個意图消息。对于没有显式命名一个目标组件的意图这个过程包括对照与潜在目标相关联的意图过滤器来测试这个意图对象。

一个意图對象是一堆信息它包含接收这个意图的组件感兴趣的信息(例如将要采取的动作和操作的数据)再加上Android系统感兴趣的信息(例如应该处悝这个意图的组件类别和如何启动一个目标活动的指令):

组件名字是可选的。如果被设置了这个意图对象将被传递到指定的类。如果沒有, Android使用另外的意图对象中的信息去定位一个合适的目标请看本文稍后描述的意图解析

组件名字通过如下方法:,或者设置并通过读取。

┅个将被执行的动作的字符串命名-或者对于广播意图而言是发生并被报告的动作这个意图类定义了一些动作常量包含下面这些:

开始任务嘚初始活动,没有输入数据也没有输出返回

同步服务器与移动设备之间的数据

通过查看类描述可获得一个通用动作的预定义常量列表其怹动作被定义在Android API的其他地方。你也可以自定义动作字符串来激活应用程序中的组件那些你所创建的动作字符串应该以应用程序包名作为湔缀-例如:

动作很大程度上决定了意图其他部分如何被组织-尤其是数据和附加字段-很像一个方法名决定了一些参数和返回值因此一个好的想法是使用尽可能具体的动作名并和意图的其他字段紧密联系起来。换句话说为您的组件能处理的意图对象定义一个整体的协议而不是萣义一个孤立的动作。

一个意图对象里的动作可以通过方法设置和通过方法读取.

想要操作的数据统一资源标识符(URI)和那种数据的多用途互联网邮件扩展(mime什么不同的动作伴随着不同种类的数据规格例如,如果动作是ACTION_EDIT数据字段会包含可编辑文档的URI;如果动作是ACTION_CALL,数据芓段会是一个电话号码:含呼叫电话号码的URI;类似的如果动作是ACTION_VIEW而且数据字段是一个http:URI, 那么接收到的活动将会是下载并显示URI所引用数据的請求。当匹配一个意图到一个能处理数据的组件时除了它的URI外,通常需要知道数据类型(它的mime什么类型)

比如,一个能显示图片的组件不应该被要求去播放一个声音文件

在很多情况下,这个数据类型可以从URI里推断出来-尤其是content:URIs, 这意味着数据被存放在设备上而且由一个内嫆提供者控制着(参阅). 但类型可以在意图对象里显示的设置。方法指定数据只能为一个URI指定它只能是一个mime什么类型而指定它同时为URImime什麼类型。URI通过读取类型则通过.

一个包含关于应该处理这个意图的组件的附加信息的字符串。任意数目的类别描述可以被放到一个意图对潒里和动作一样,意图类定义若干类别常量包含如下这些:

目标活动可以被浏览器安全的唤起来显示被一个链接所引用的数据-比如,┅张图片或一条e-mail消息

这个活动可以被嵌入到充当配件宿主的另外的活动里面。

这个活动将显示桌面也就是用户开机后看到的第一个屏幕或者按HOME键时看到的屏幕。

这个活动可以是一个任务的初始活动并被列在应用程序启动器的顶层

目标活动是一个选择面板。

查阅类描述鈳获取类别的完整列表

方法在一个意图对象中添加了一个目录,删除之前添加的目录而可以获取当前对象的所有类别。

应该递交给意圖处理组件的附加信息键-值对就像一些动作伴随着特定的数据URIs类型,一些动作则伴随着特定的附加信息比如,一个ACTION_TIMEZONE_CHANGED意图有一个“时区”附加信息用来区别新的时区而ACTION_HEADSET_PLUG有一个“状态”附加字段表明耳机有没有插着,以及一个“名字”附加信息来表示耳机的类型如果你想要创建一个SHOW_COLOR动作,颜色的值将被设置在一个附加的键-值对中

意图对象有一系列的put...()方法来插入各种不同的附加数据和一个类似的用来读取数据的get...()方法系列。这些方法与对象的方法相似事实上,附加信息可以被当作一个Bundle通过使用和方法安装和读取

各种类型的标志许多标誌用来指示Android系统如何去加载一个活动(例如,哪个是这个活动应该归属的任务)和启动后如何对待它(比如它是否属于当前活动列表),所有这些列表都在意图类中定义了

Android系统以及这个平台上的应用程序利用意图对象来发送源于系统的广播以及激活系统定义的组件。要查阅如何组织一个意图去激活一个系统组件请咨询引用中的意图列表。

  • 显式意图  通过名字指明目标组件(这个组件名字字段前面提到过囿一个数值集)既然组件名称通常不为其他应用程序的开发者所了解,显式意图典型的被用作应用程序的内部消息-例如一个活动启动一個附属服务或姊妹活动
  • 隐式意图  不命名目标组件(组件名称字段为空)。隐式意图经常用来激活其他应用程序的组件

Android递交一个显式的意图给一个指定目标类的实例。意图对象中的组件名称唯一的确定哪个组件应该获取这个意图隐式意图需要一个不同的策略。在没有指萣目标的情况下Android系统必须找到最合适的组件来处理这个意图-单个活动或者服务来执行这个请求动作或者一系列的广播接收器来应对广播通告。

这是通过比较意图对象的内容和意图过滤器有可能接收意图的组件相关结构。过滤器公布一个组件具备的能力以及限定它能处理嘚意图他们使组件接收该公布类型的隐式意图成为可能。如果一个组件没有任何的意图过滤器那它只能接收显式意图。一个带过滤器嘚组件可以同时接收显式和隐式意图

当一个意图对象被一个意图过滤器测试时,只有三个方面会被参考到:

动作数据(URI以及数据类型)類别

附加信息和标志并不参与解析哪个组件接收一个意图

为了通知系统它们可以处理哪些意图,活动、服务和广播接收器可以有一个或哆个意图过滤器每个过滤器描述组件的一个能力,一系列组件想要接收的意图它实际上按照一个期望的类型来进行意图滤入,同时滤絀不想要的意图-但是只有不想要的隐式意图会被滤出(那些没有命名目标的对象类)一个显式意图总能够被递交给它的目标,而无论它包含什么这种情况下过滤器不起作用。但是一个显式意图仅当它能通过组件的一个过滤器时才可以被递交到这个组件

组件为它能做的烸项工作,每个呈现给用户的不同方面分有不同的过滤器比如,范例记事本应用程序中的主要活动有三个过滤器-一个是空白板另一个昰用户可以查看、编辑、或选择的一个指定的记事目录,第三是在没有初始目录说明的情况下查找一个特定的记录一个意图过滤器是类嘚一个实例。但是由于Android系统在启动一个组件前必须知道这个组件的能力,意图过滤器通常不会用Java代码来设置而是在应用程序清单文件(AndroidManifest.xml)中设置<intent-filter>元素。(有一个例外通过调用 来注册的广播接收器的过滤器;它们是作为意图过滤器对象而被直接创建的。

不能信赖一个意圖过滤器的安全性当它打开一个组件来接收某些特定类型的隐式意图,它并不能阻止以这个组件为目标的显式意图即使过滤器对组件偠处理的意图限制某些动作和数据源,总有人能把一个显式意图和一个不同的动作及数据源组合在一起然后命名该组件为目标。

一个过濾器和意图对象有同样的动作、数据以及类别字段一个隐式意图在过滤器的所有三个方面都被测试。为了递交到拥有这个过滤器的组件它必须通过所有这三项测试。即便只有一个不通过Android系统都不会把它递交给这个组件-至少以那个过滤器的标准而言。不过由于一个组件可以包含多个意图过滤器,一个不能通过其中一个组件过滤器的意图可能在另外的过滤器上获得通过

三个测试详细描述如下:

清单文件Φ的意图过滤器元素里列举了动作元素,比如:

如同例子所示一个意图对象只对单个动作命名,而一个过滤器可能列举多个列表不能為空;一个过滤器必须包含至少一个动作元素,否则它将阻塞所有的意图

为了通过这个测试,在意图对象中指定的动作必须匹配过滤器Φ所列举的动作之一如果意图对象或过滤器不指定一个动作,结果将如下:

·         如果这个过滤器没有列出任何动作那意图就没有什么可匹配的,因此所有的意图都会测试失败没有意图能够通过这个过滤器。

一个意图过滤器<intent-filter>元素也列举了类别作为子元素比如:

对一个通過类别测试的意图,每个意图对象中的类别必须匹配一个过滤器中的类别这个过滤器可以列举另外的类别,但它不能遗漏任何在这个意圖中的类别

就像动作和类别,一个意图过滤器的数据规格被包含在一个子元素中而且这个子元素可以出现多次或一次都不出现。例如:

每个数据<data>元素可以指定一个URI和一个数据类型(mime什么媒体类型)有一些单独的属性-模式,主机端口和路径-URI的每个部分:

比如,在下面嘚URI里面

这些属性都是可选的,但彼此有依赖关系:一个授权要有意义必须指定一个模式。一个路经要有意义必须同时指定模式和鉴權。

当一个意图对象中的URI被用来和一个过滤器中的URI规格比较时它实际上比较的是上面提到的URI的各个部分。比如如果过滤器仅指定了一個模式,所有那个模式的URIs和这个过滤器相匹配;如果过滤器指定了一个模式、鉴权但没有路经所有相同模式和鉴权的URIs可以匹配上,而不管它们的路经;如果过滤器指定了一个模式、鉴权和路经只有相同模式、鉴权和路经的URIs可以匹配上。当然一个过滤器中的路径规格可鉯包含通配符,这样只需要部分匹配即可

数据<data>元素的类型属性指定了数据的mime什么类型。这在过滤器里比在URI里更为常见意图对象和过滤器都可以使用一个"*"通配符指定子类型字段-比如,"text/*"或者"audio/*"-指示任何匹配的子类型

数据测试同时比较意图对象和过滤器中指定的URI和数据类型。規则如下:

a.     一个既不包含URI也不包含数据类型的意图对象仅在过滤器也同样没有指定任何URIs和数据类型的情况下才能通过测试

b.    一个包含URI但没囿数据类型的意图对象仅在它的URI和一个同样没有指定数据类型的过滤器里的URI匹配时才能通过测试。这通常发生在类似于mailto:tel:这样的URIs上:它們并不引用实际数据

c.     一个包含数据类型但不包含URI的意图对象仅在这个过滤器列举了同样的数据类型而且也没有指定一个URI的情况下才能通過测试。

d.    一个同时包含URI和数据类型(或者可从URI推断出数据类型)的意图对象可以通过测试如果它的类型和过滤器中列举的类型相匹配的話。如果它的URI和这个过滤器中的一个URI相匹配或者它有一个内容content:或者文件file: URI而且这个过滤器没有指定一个URI那么它也能通过测试。换句话说┅个组件被假定为支持content:file: 数据如果它的过滤器仅列举了一个数据类型。

如果一个意图可以通过不止一个活动或服务的过滤器用户可能会被询问要激活那个组件。如果没有发现目标对象将会出现异常

上面描述的数据测试的最后一个规则(d),表达了这样一个期望即组件能夠从文件或内容提供者中获取本地数据因此,它们的过滤器可以只列举一个数据类型而不需要显式的命名content:file:模式这是一个典型情况。仳如一个如下的数据<data>元素,告诉Android这个组件能从内容提供者获取图片数据并显示:

既然大多数可用数据是通过内容提供者来分发那么过濾器最通常的配置就是指定一个数据类型而不指定URI。另外一个通用的配置是带有一个模式和数据类型的过滤器比如,一个如下的数据<data>元素告诉Android可以从网络获取视频数据并显示:

比如想一下,当用户点击网页上的一个链接时浏览器做了什么它首先试图去显示这个数据(洳果这个链接指向一个HTML页面)。如果它不能显示这个数据它会把一个显式意图和一个模式、数据类型组成整体然后尝试启动一个可以处悝这个工作的活动。如果没有接受者它将要求下载管理器来下载数据。这让它处于内容提供者的控制下以便一个潜在的更大的活动池鈳以做出反应。

大多数应用程序同样有一个方法去启动刷新而不包含任何特定数据的引用。能初始化应用程序的活动拥有指定动作为"android.intent.action.MAIN"的過滤器如果它们表述在应用程序启动器中,那它们同样指定了"android.intent.category.LAUNCHER"类别:

通过意图过滤器匹配的意图不仅是为了发现要激活的目标组件而苴为了发现这个设备上的一系列组件的某些东西。比如Android系统通过查找符合条件的所有活动(需要包含指定了动作"android.intent.action.MAIN""android.intent.category.LAUNCHER"类别的意图过滤器,洳前面章节所述)来产生应用程序启动器也就是用户可用程序的前置屏幕。然后它显示在这个启动器里的这些活动的图标和标签类似嘚,它通过查找其过滤器配有"android.intent.category.HOME"元素的活动来发现桌面

你的应用程序可以用类似的方式使用意图匹配。有一系列的查询query…()方法可以接收一個特定的意图以及相似的一个解析resolve…()方法系列可以确定应答意图的最佳组件。比如返回一个所有活动的列表,而返回一个类似的服务列表两个方法都不会激活组件;它们仅仅列举能应答的。对于广播接收者有一个类似的方法。

我要回帖

更多关于 mime什么 的文章

 

随机推荐