<uri-relative-filter-group>

синтаксис:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
содержится в:
<intent-filter>
может содержать:
<data>
описание:
Создает точные правила сопоставления Intent , которые могут включать параметры запроса URI и фрагменты URI. Правила могут быть правилами включения ( allow ) или правилами исключения ( блокировки ), в зависимости от атрибута 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> объединяются по логическому оператору OR, а теги <data> внутри <uri-relative-filter-group> объединяются с помощью AND.

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

<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 в зависимости от наличия или значения параметра запроса. Чтобы создать фильтр намерений, соответствующий 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 .

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

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

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

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

Информацию о <uri-relative-filter-group> см. в UriRelativeFilterGroup и UriRelativeFilter .

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