- syntax:
-
<uri-relative-filter-group android:allow=["true" | "false"]> <data ... /> ... </uri-relative-filter-group>
- contained in:
-
<intent-filter>
- can contain:
-
<data>
- description:
-
Creates precise
Intent
matching rules that can include URI query parameters and URI fragments. The rules can be inclusion (allow) rules or exclusion (blocking) rules, depending on theandroid:allow
attribute. The matching rules are specified by thepath*
,fragment*
, andquery*
attributes of the contained<data>
elements.Matching
To match a URI, each portion of the URI relative filter group must match a part of the URI. There can be portions of the URI that are not specified in the URI relative filter group. For example:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="true"> <data android:query="param1=value1" /> <data android:query="param2=value2" /> </uri-relative-filter-group> ... </intent-filter>
The filter matches
https://project.example.com/any/path/here?param1=value1¶m2=value2¶m3=value3
because everything specified by the URI relative filter group is present. The filter also matcheshttps://project.example.com/any/path/here?param2=value2¶m1=value1
because the order of the query parameters doesn't matter. However, the filter doesn't matchhttps://project.example.com/any/path/here?param1=value1
, which is missingparam2=value2
.OR and AND
<data>
tags outside a<uri-relative-filter-group>
are ORed, while<data>
tags inside of a<uri-relative-filter-group>
are ANDed.Consider the following example:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <data android:pathPrefix="/prefix" /> <data android:pathSuffix="suffix" /> ... </intent-filter>
The filter matches paths that start with
/prefix
OR end withsuffix
.In contrast, the next example matches paths that start with
/prefix
AND end withsuffix
:<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group> <data android:pathPrefix="/prefix" /> <data android:pathSuffix="suffix" /> </uri-relative-filter-group> ... </intent-filter>
As a result, multiple
path
attributes in the same<uri-relative-filter-group>
don't match anything:<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group> <data android:path="/path1" /> <data android:path="/path2" /> </uri-relative-filter-group> ... </intent-filter>
Declaration order
Consider the following example:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group> <data android:fragment="fragment" /> </uri-relative-filter-group> <uri-relative-filter-group android:allow="false"> <data android:fragmentPrefix="fragment" /> </uri-relative-filter-group> ... </intent-filter>
The filter matches the fragment
#fragment
because a match is found before the exclusion rule is evaluated, but fragments like#fragment123
don't match.Sibling tags
<uri-relative-filter-group>
tags work together with their sibling<data>
tags (that is,<data>
tags that are are outside the<uri-relative-filter-group>
but inside the same<intent-filter>
).<uri-relative-filter-group>
tags must have sibling<data>
tags to function properly because URI attributes are mutually dependent at the<intent-filter>
level:- If a
scheme
isn't specified for the intent filter, all the other URI attributes are ignored. - If a
host
isn't specified for the filter, theport
attribute and all thepath*
attributes are ignored.
The
<data>
children of an<intent-filter>
are evaluated before any<uri-relative-filter-group>
tags. Then the<uri-relative-filter-group>
tags are evaluated in order, for example:<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="false"> <data android:path="/path" /> <data android:query="query" /> </uri-relative-filter-group> <data android:path="/path" /> ... </intent-filter>
The filter accepts
https://project.example.com/path?query
because it matches<data android:path="/path" />
, which is outside the<uri-relative-filter-group>
exclusion rule.Common use case
Imagine you have the URI
https://project.example.com/path
, which you want to match to anIntent
depending on the presence or value of a query parameter. To create an intent filter that matcheshttps://project.example.com/path
and blockshttps://project.example.com/path?query
, you might try something like:<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="true"> <data android:path="/path" /> </uri-relative-filter-group> ... </intent-filter>
This, in fact, doesn't work. The
https://project.example.com/path?query
URI matches the path/path
, and the<uri-relative-filter-group>
tag allows extra parts when it is matching.Revise the intent filter as follows:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="false"> <data android:path="/path" /> <data android:queryAdvancedPattern=".+" /> </uri-relative-filter-group> <uri-relative-filter-group android:allow="true"> <data android:path="/path" /> </uri-relative-filter-group> ... </intent-filter>
This filter works because the blocking rules that forbid nonempty query parameters are evaluated first.
To simplify the code, flip the behavior to allow query parameters and block URIs without query parameters:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="true"> <data android:path="/path" /> <data android:queryAdvancedPattern=".+" /> </uri-relative-filter-group> ... </intent-filter>
URI-encoded characters
To match URIs that contain URI-encoded characters, write the raw, unencoded characters in the filter, for example:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="true"> <data android:query="param=value!" /> </uri-relative-filter-group> ... </intent-filter>
The filter matches
?param=value!
and?param=value%21
.However, if you write encoded characters in the filter as follows:
<intent-filter...> <data android:scheme="https" android:host="project.example.com" /> <uri-relative-filter-group android:allow="true"> <data android:query="param=value%21" /> </uri-relative-filter-group> ... </intent-filter>
The filter matches neither
?param=value!
nor?param=value%21
.Number of elements
You can place any number of
<uri-relative-filter-group>
elements inside an<intent-filter>
.Additional resources
For information on how intent filters work, including the rules for how intent objects are matched against filters, see Intents and Intent Filters and Intent Filters.
For information on
<uri-relative-filter-group>
, seeUriRelativeFilterGroup
andUriRelativeFilter
. - If a
- attributes:
-
android:allow
-
Whether this URI relative filter group is an inclusion (allow) rule rather than
an exclusion (blocking) rule. The default value is
"true"
.Value Description "true"
(default)If the URI relative filter group matches, the intent filter matches "false"
If the URI relative filter group matches, the intent filter doesn't match
- introduced in:
- API level 35
- see also:
-
<intent-filter>
<data>
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2024-12-02 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-12-02 UTC."],[],[]]