An Intent Filter specifies a set of values to be matched against Intents.
Values may be specified to match against any or all of the following parts of an Intent
-
the action
-
the data
-
the data type
-
the categories
1. Actions
An Intent Filter may specify zero or more actions to match against the action specified by an Intent.
2. Data
An Intent Filter may specify
-
a non-empty set of schemes, or
-
a non-empty set of schemes and a non-empty set of authorities, or
-
a non-empty set of schemes and a non-empty set of authorities and a non-empty set of paths
to match against the data specified by an Intent.
Although it is also possible for an Intent Filter to specify the following,
-
a non-empty set of authorities only, or
-
a non-empty set of paths only, or
-
a non-empty set of authorities and a non-empty set of paths only
they will NOT be used when matching against the data specified by an Intent.
2.2 Schemes
A scheme specifies a case-sensitive URI scheme to match against the scheme of a data URI specified by an Intent
2.3 Authorities
An authority specifies a host, and optionally a port, to match the authority part of a network data URI specified by an Intent.
2.4 Paths
A path to match against the data URI specified by an Intent can be specified as
-
a literal, which the path part of the data URI must be equal to,
-
a prefix, which the path part of the data URI must start with, or
-
a simple pattern, which the path part of the data URI must match
The syntax of a simple pattern is as follows
-
The expression
<char>'*'
matches zero or more occurences of<char>
-
The character
'.'
matches any character. -
The character
'\'
escapes the following character.
3. Data Types
An IntentFilter can specify zero or more MIME types to match against the type of the data specified by an Intent.
4. Categories
An Intent Filter can specify zero or more categories to match against the set of categories specified by an Intent.
5. The intent-filter XML Element
An Intent Filter can be specified in the manifest of an Application using the
intent-filter
element.
5.1 Attributes
All the attributes of this element pertain to the Application Component which declares it rather than to the Intent Filter itself.
5.1.1 The icon Attribute
If present the icon attribute specifies a drawable resource which the system should use to visually identify the Application Component with which this Intent Filter declaration is associated.
5.1.2 The label Attribute
If present the label attribute specifies a string resource which the system should use to label the Application Component with which this Intent Filter declaration is associated.
5.1.3 The priority Attribute
If present the priority attribute specifies an integer value to be used by the system if it is necessary to compute an ordering on a set of Application Components all of which have associated Intent Filters which match a given Intent.
5.2 Child Elements
5.2.1 The action Element
The action
element has a single attribute
name
which specifies the action. This attribute must be present.
There are no child elements.
The element must appear at least once. It may appear multiple times.
5.2.2 The category Element
The category
element has a single attribute
name
which specifies the category. This attribute must be present.
There are no child elements.
The element may appear zero or more times.
5.2.3 The data Element
The data
element may appear zero or more times.
It has no child elements. All values are specified using attributes.
The exact set of attributes associated with an individual data
element is not significant.
For example, these three elements
<data scheme="http"/>
<data host="justanapplication.wordpress.com"/>
<data pathPrefix="/2010"/>
are equivalent to this one.
<data scheme="http" host="justanapplication.wordpress.com" pathPrefix="/2010"/>
The values specified by each element are aggregated to make up the IntentFilter’s sets of schemes, authorities, paths and types.
The validity of the authority and path sets that result are governed by the rules defined here.
5.2.3.1 The Attributes
5.2.3.1.1 Specifying A Scheme
A scheme can be specified using the scheme
attribute.
5.2.3.1.2 Specifying An Authority
The host and port parts of an authority can be specified using the host
and port
attributes respectively.
A data
element may have a host
attribute without an associated port
attribute. However, if a data
element does not have a host
attribute, but it does have a port
attribute, then the port
attribute is ignored.
5.2.3.1.3 Specifying A Path
A path can be specified as a
- a literal,
- a prefix, or
- a simple pattern
using the
path
pathPrefix
, orpathPattern
attributes respectively.
All three attributes may be present on the same element.
5.2.3.1.3 Specifying A Data Type
A data type can be specified by using mimeType
attribute.
The value of the attribute must be a valid MIME type of the form <type>/<sub-type>
. It is an error if it is not.
6. The IntentFilter class
An Application can specify an Intent Filter at runtime using an instance of the class
android.content.IntentFilter
The system itself uses sub-classes of this class to represent both statically and dynamically specified Intent Filters associated with Application Components.
An IntentFilter
instance may contain
-
a set of actions
-
a set of schemes
-
a set of authorities
-
a set of paths
-
a set of MIME types
-
a set of categories
6.1 Construction
The IntentFilter
class has four public constructors
public IntentFilter()
public IntentFilter(String action)
public IntentFilter(String action, String dataType)
public IntentFilter(IntentFilter o)
An instance of IntentFilter is mutable so only the default constructor is strictly necessary, but IntentFilters with a single action are fairly heavily used by the system itself hence at least one of the convenience constructors.
6.2 Actions
An action can be added to an IntentFilter’s set of actions using the method
public final void addAction(String action)
The format of the action
argument is not checked, although it cannot be null
.
6.3 Data
6.3.1 Schemes
A scheme can be added to an IntentFilter’s set of schemes using the method
public final void addDataScheme(String scheme)
The format of the scheme
argument is not checked, although it cannot be null
.
6.3.2 Authorities
An authority can be added to an IntentFilter’s set of authorities using the method
public final void addDataAuthority(String host, String port)
The host
argument may start with the wildcard character ('*'
) in which case it specifies a suffix to match. It cannot be null
.
The port
may be null
. If it is not then it must be a representation of an integer capable of being parsed by the Integer
method
public int parseInt(String string)
or a NumberFormatException
will be thrown.
Whether adding an authority using this method will actually have any effect on the matching of an Intent’s data URI depends on the rules outlined here.
6.3.3 Paths
A path can be added to the IntentFilter’s set of paths using the method
public final void addDataPath(String path, int type)
The value of the type
argument must be one of the following android.os.PatternMatcher
class constants
-
PATTERN_LITERAL
-
PATTERN_PREFIX
-
PATTERN_SIMPLE_GLOB
and it specifies that the path
argument is to be interpreted as a
respectively.
Whether adding a path using this method will actually have any effect effect on the matching of an Intent’s data URI depends on the rules outlined here.
6.4 Data Types
A MIME type can be added to the IntentFilter’s set of data types using the method
public final void addDataType(String type)
Unlike the methods used to set explicitly the data type of an Intent, the format of the type
argument is verified.
It must be of the form
<type> '/' <sub-type>
Both the type and the sub-type must at least of length one.
Both the type and the sub-type can be the wildcard character '*'
, in which case it specifies the wildcard type which matches any type.
Alternatively only the sub-type may be the wildcard character in which it case it matches any sub-type of the given type.
6.5 Categories
A category can be added to the IntentFilter’s set of categories using the method
public final void addCategory(String category)
The format of the category
argument is not checked, although it cannot be null
.
7. Matching
An IntentFilter can be used to match the following constituents of an Intent, either individually or collectively.
-
the action
-
the data
-
the data type
-
the categories
7.1 Method Return Values
Some IntentFilter matching methods return an integer status, a negative value indicating that the match failed, a positive value that the match succeeded.
7.1.1 Matching Failures
A matching failure is specified using the value of one of the IntentFilter
class constants
Class Constant | Value | Reason |
---|---|---|
NO_MATCH_TYPE |
-1 |
type did not match |
NO_MATCH_DATA |
-2 |
data did not match |
NO_MATCH_ACTION |
-3 |
action did not match |
NO_MATCH_CATEGORY |
-4 |
categories did not match |
7.1.2 Matching Success
The integer value returned when a match succeeded can comprise two parts.
The top twelve bits always specifies the match category
, that is, what matched, and the bottom sixteen bits may specify a quality adjustment
The possible values of the match category
part are defined by the following class constants
Class Constant | Value |
---|---|
MATCH_CATEGORY_EMPTY |
0x100000 |
MATCH_CATEGORY_SCHEME |
0x200000 |
MATCH_CATEGORY_HOST |
0x300000 |
MATCH_CATEGORY_PORT |
0x400000 |
MATCH_CATEGORY_PATH |
0x500000 |
MATCH_CATEGORY_TYPE |
0x600000 |
Although the constant returned is dependent on what matched in a given context, the distinction being made may not be that useful.
For example, the documentation for MATCH_CATEGORY_HOST
reads
The filter matched an intent with the same data URI scheme and authority host.
which is true when it is returned from matchData() but not matchDataAuthority().
The documentation for MATCH_CATEGORY_TYPE
reads
The filter matched an intent with the same data MIME type.
which is true as far as it goes.
MATCH_CATEGORY_TYPE
is only ever returned by the method matchData() and it certainly will not return it if the IntentFilter does not match the given type, but it can mean anything from there was only a type given and it matched up to everything matched, that is, scheme, host, port, path and type all matched.
The IntentFilter
class constants
MATCH_ADJUSTMENT_MASK
and
MATCH_CATEGORY_MASK
specify the bit masks to use to extract the respective parts.
7.2 Matching Against An Action
An IntentFilter can be used to match against an action using the IntentFilter
method
public final boolean matchAction(String action)
This method will return true
if and only if the action is not null
and it is a member of the IntentFilter’s set of actions.
Note
The method documentation is actually contradictory. It states that
If the filter does not specify any actions, the match will always fail.
which is correct.
It then goes on to say that it returns
True if the action is listed in the filter or the filter does not specify any actions. [Emphasis added]
the second part of which is not.
7.3 Matching Against A Data Type, Scheme, and URI
An IntentFilter can be used to match against a data type, scheme and URI using the IntentFilter
method
public final int matchData(String type, String scheme, Uri data)
The method first attempts to match against the scheme and the URI and then, against the type.
7.3.1 Matching The Scheme And URI
7.3.2.1 Case: Non-Empty Set Of Schemes
If the IntentFilter specifies one or more schemes then the match will succeed
-
if the
scheme
argument is non-null
and it is a member of the IntentFilter’s set of schemes, or -
it is
null
and the empty String (“”) is a member of the IntentFilter’s set of schemes.
7.3.2.1.1 Case: Non-Empty Set Of Schemes And Non-Empty Set Of Authorities
If the IntentFilter specifies one or more schemes and the scheme matching succeeds, then if it also specifies one or more authorities, the match will succeed if one of the specified authorities matches the authority part of the URI. The matching is done using the matchDataAuthority()
method.
7.3.2.1.1.1 Case: Non-Empty Set Of Schemes And Non-Empty Set Of Authorities And Non-Empty Set Of Paths
If the IntentFilter specifies one or more schemes and the scheme matching succeeds, and it specifies one or more authorities and the authority matching succeeds, then if it also specifies one or more paths the match will succeed if the data URI has a path part which at least one of the specified paths matches.
7.3.2.2 Case: Empty Set Of Schemes And Non-Empty Set Of Types
If the IntentFilter does not specify any schemes then the match will succeed if the value of the scheme
argument is one of the following
-
null
-
“” (the empty String)
-
“content”
-
“file”
7.3.2 Matching The Type
If the matching of the scheme and URI succeeds then the type is matched.
7.3.2.1 Case: Non-Empty Set Of Types
If the IntentFilter specifies one or more types then the match will succeed if one of the specified types matches the type
argument.
A specified type will match the type
argument
-
if it is equal to it
-
if it is the wildcard type (
*/*
) -
if it is a type/wildcard pair (
<type>/*
) which matches.
For example, given
IntentFilter f1 = new IntentFilter();
f1.addDataType("image/png");
IntentFilter f2 = new IntentFilter();
f2.addDataType("*/*");
IntentFilter f3 = new IntentFilter();
f3.addDataType("image/*");
the following matches all succeed
f1.matchData("image/png", null, null) // returns 0x608000
f2.matchData("image/png", null, null) // returns 0x608000
f3.matchData("image/png", null, null) // returns 0x608000
Rather less obviously the match will also succeed if the type
argument is
-
the wildcard type (
*/*
), or -
a type/wildcard pair (
<type>/*
) which matches a type/sub-type pair specified by the IntentFilter.
For example given
IntentFilter f = new IntentFilter();
f.addDataType("image/png");
then the following both succeed
f.matchData("*/*", null, null) // returns 0x608000
f.matchData("image/*", null, null) // returns 0x608000
The format of the type
argument is not checked but if it is not in the type/sub-type format the match will fail.
For example, given the same IntentFilter as above
IntentFilter f = new IntentFilter();
f.addDataType("image/png");
then this fails
f.matchData("image", null, null) // returns -1
despite the fact that there is an argument for saying that image
and image/*
are pretty much the same thing,
It is worth noting this because when the data type of an Intent is set explicitly the format is not checked, so it quite feasible to set it to something like image
.
7.3.2.2 Case: Empty Set Of Types And Non-Empty Set Of Schemes
If the IntentFilter does not specify any types then the match will only succeed if the type
argument is null
.
7.3.3 Edge Case (Strange But True): Empty Set Of Schemes And Empty Set Of Types
The method actually looks for this edge case first.
If the IntentFilter does not specify any schemes or types and the data
and type
arguments are both null
then the match will succeed for any value of the scheme
argument.
For example
new IntentFilter().matchData(null, "http", null) // returns 0x108000
and also
new IntentFilter().matchData(null, "not really a scheme at all", null) // returns 0x108000
If the data
and type
arguments are not both null
the match will fail.
7.4 Matching Against A Data Authority
An IntentFilter can be used to match against the authority part of a URI using the IntentFilter
method
public final int matchDataAuthority(Uri data)
The match will succeed if the IntentFilter specifies one or more authorities, the URI specifies a host, or a host and a port, and at least one of the specfied authorities matches the host, or host and port, specified by the URI.
An authority will match the URI if
-
the URI specifies a host and a port, the authority specifies a host and a port, and they match, or
-
the URI specifies a host, it may or may not specify a port, the authority only specifies a host, and the specified hosts match
Note
Although the documentation is adamant that
[the] host name in the Android framework is case-sensitive, unlike formal RFC host names
nobody seems to have told the source code of this method which is using the String
method
public int compareToIgnoreCase(String string)
to do the matching of the hosts, so given
IntentFilter f = new IntentFilter();
f.addDataAuthority("justanapplication.wordpress.com", null);
and
Uri uriLC = new Uri.Builder().scheme("http").authority("justanapplication.wordpress.com").build();
Uri uriMC = new Uri.Builder().scheme("http").authority("JustAnApplication.WordPress.Com").build();
Uri uriUC = new Uri.Builder().scheme("http").authority("JUSTANAPPLICATION.WORDPRESS.COM").build();
then the following all succeed
f.matchDataAuthority(uriLC) // returns 0x300000
f.matchDataAuthority(uriMC) // returns 0x300000
f.matchDataAuthority(uriUC) // returns 0x300000
7.5 Matching Against A Set Of Categories
An IntentFilter can be used to match against a set of categories using the IntentFilter
method
public final String matchCategories(Set<String> categories)
The match will succeed if the set specified by the categories
argument is equal to, or a sub-set of, the set of categories specified by the IntentFilter.
If the match fails the method will return the first category in the categories
argument which is not a member of the set of categories specified by the IntentFilter.
If the match succeeds then the method will return null
.
For example, assuming there are four categories defined by the class constants
-
CATEGORY_FOO
-
CATEGORY_BAR
-
CATEGORY_BAZ
-
CATEGORY_MUMBLE
five Intents constructed as follows
Intent i0 = new Intent();
Intent i1 = new Intent().
addCategory(
CATEGORY_FOO);
Intent i2 = new Intent(i1).
addCategory(
CATEGORY_BAR);
Intent i3 = new Intent(i2).
addCategory(
CATEGORY_BAZ);
Intent i4 = new Intent(i3).
addCategory(
CATEGORY_MUMBLE);
and an IntentFilter constructed as follows
IntentFilter f = new IntentFilter();
f.addCategory(CATEGORY_FOO);
f.addCategory(CATEGORY_BAR);
f.addCategory(CATEGORY_BAZ);
then the following
f.matchCategories(i0.getCategories()) // null
f.matchCategories(new HashSet<String>()) // empty set
f.matchCategories(i1.getCategories()) // sub-set
f.matchCategories(i2.getCategories()) // sub-set
f.matchCategories(i3.getCategories()) // equals
will all match and return null
, and this
f.matchCategories(i4.getCategories())
will not match and will return the value of CATEGORY_MUMBLE
.
Note especially that if the set of categories to match is null
or empty then the match will always succeed.
7.6 Matching Against An Intent
An IntentFilter can be used to match against all the constituent parts of an Intent using the IntentFilter
method
public final int match(
String action,
String type,
String scheme,
Uri data,
Set<String> categories,
String logTag)
It is this method that the system uses to match IntentFilters against the parts of an Intent.
The method uses the matchAction(), matchData() and matchCategories() methods in combination to determine whether there is a match, but with one subtle difference.
While this will fail
new IntentFilter().matchAction(null) // returns false
this will not
new IntentFilter().match(null, null, null, null, null, null) // returns 0x108000
Copyright (c) 2010 By Simon Lewis. All Rights Reserved.