<uri-relative-filter-group>

синтаксис:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
содержится в:
<intent-filter>
может содержать:
<data>
описание:
Создает точные правила сопоставления Intent , которые могут включать параметры запроса URI и фрагменты URI. Правила могут быть правилами включения ( разрешить ) или правилами исключения ( блокировать ), в зависимости от атрибута android: allow . Правила сопоставления задаются атрибутами path* , fragment* и query* содержащихся элементов <data> .

Соответствие

Для сопоставления URI каждая часть группы относительных фильтров URI должна соответствовать части URI. В группе относительных фильтров URI могут быть части URI, не указанные в ней. Например:

<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>

Фильтр соответствует https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3 , поскольку присутствуют все параметры, указанные в группе фильтров относительно URI. Фильтр также соответствует https://project.example.com/any/path/here?param2=value2&param1=value1 поскольку порядок параметров запроса не имеет значения. Однако фильтр не соответствует https://project.example.com/any/path/here?param1=value1 , поскольку отсутствует param2=value2 .

ИЛИ и И

Теги <data> , находящиеся вне <uri-relative-filter-group> , объединяются в операцию ИЛИ, а теги <data> , находящиеся внутри <uri-relative-filter-group> , объединяются в операцию И.

Рассмотрим следующий пример:

<intent-filter...>
  <data android:scheme="https" android:host="project.example.com" />
  <data android:pathPrefix="/prefix" />
  <data android:pathSuffix="suffix" />
  ...
</intent-filter>

Фильтр соответствует путям, начинающимся с /prefix ИЛИ заканчивающимся suffix .

В противоположность этому, следующий пример соответствует путям, начинающимся с /prefix И заканчивающимся suffix :

<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>

В результате, несколько атрибутов path в одной и той же группе <uri-relative-filter-group> не соответствуют ни одному условию:

<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>

Декларационный приказ

Рассмотрим следующий пример:

<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>

Фильтр соответствует фрагменту #fragment поскольку совпадение найдено до того, как будет оценено правило исключения, но фрагменты типа #fragment123 не соответствуют.

Теги для братьев и сестер

Теги <uri-relative-filter-group> работают совместно со своими соседними тегами <data> (то есть, тегами <data> , которые находятся вне <uri-relative-filter-group> , но внутри того же <intent-filter> ). Для корректной работы теги <uri-relative-filter-group> должны иметь соседние теги <data> , поскольку атрибуты URI взаимно зависят на уровне <intent-filter> :

  • Если для фильтра намерений не указана scheme , все остальные атрибуты URI игнорируются.
  • Если для фильтра не указан host , атрибут port и все атрибуты path* игнорируются.

Дочерние элементы <data> из <intent-filter> оцениваются до любых тегов <uri-relative-filter-group> . Затем теги <uri-relative-filter-group> оцениваются в порядке следования, например:

<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>

Фильтр принимает https://project.example.com/path?query поскольку он соответствует <data android:path="/path" /> , что выходит за рамки правила исключения <uri-relative-filter-group> .

Типичный сценарий использования

Представьте, что у вас есть URI https://project.example.com/path , и вы хотите сопоставить его с Intent в зависимости от наличия или значения параметра запроса. Чтобы создать фильтр Intent, который соответствует https://project.example.com/path и блокирует https://project.example.com/path?query , вы можете попробовать что-то вроде:

<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>

На самом деле это не работает. URI https://project.example.com/path?query соответствует пути /path , а тег <uri-relative-filter-group> допускает дополнительные части при совпадении.

Измените фильтр намерений следующим образом:

<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>

Этот фильтр работает потому, что сначала оцениваются правила блокировки, запрещающие непустые параметры запроса.

Для упрощения кода измените поведение, разрешив параметры запроса и заблокировав URI без параметров запроса:

<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

Чтобы сопоставить URI, содержащие символы, закодированные в формате URI, в фильтр следует вводить сами незакодированные символы, например:

<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>

Фильтр соответствует параметрам ?param=value! и ?param=value%21 .

Однако, если вы введете закодированные символы в фильтр следующим образом:

<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>

Фильтр не соответствует ни ?param=value! ни ?param=value%21 .

Количество элементов

Внутри элемента <intent-filter> можно разместить любое количество элементов <uri-relative-filter-group> .

Дополнительные ресурсы

Информацию о том, как работают фильтры намерений, включая правила сопоставления объектов намерений с фильтрами, см. в разделах «Намерения» и «Фильтры намерений» , а также «Фильтры намерений» .

Для получения информации о <uri-relative-filter-group> см. UriRelativeFilterGroup и UriRelativeFilter .

атрибуты:
android:allow
Определяет, является ли эта группа относительных фильтров URI правилом включения ( разрешить ), а не правилом исключения ( блокировать ). Значение по умолчанию — "true" .
Ценить Описание
"true" (по умолчанию) Если группа фильтров, относительных к URI, совпадает, то и фильтр намерения совпадает.
"false" Если группа фильтров, относящихся к URI, совпадает, то фильтр намерений не совпадает.
введено в:
Уровень API 35
См. также:
<intent-filter>
<data>