<uri-relative-filter-group>

sintaxis:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
se incluye en:
<intent-filter>
puede contener:
<data>
descripción:
Crea reglas de coincidencia Intent precisas que pueden incluir parámetros de consulta de URI y fragmentos de URI. Las reglas pueden ser de inclusión (permitir) o de exclusión (bloquear), según el atributo android:allow. Los atributos path*, fragment* y query* de los elementos <data> contenidos especifican las reglas de coincidencia.

Coincidencias

Para que coincida con un URI, cada parte del grupo de filtros relativos del URI debe coincidir con una parte del URI. Puede haber partes del URI que no se especifiquen en el grupo de filtros relativo del URI. Por ejemplo:

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

El filtro coincide con https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3 porque está presente todo lo que especifica el grupo de filtros relativos del URI. El filtro también coincide con https://project.example.com/any/path/here?param2=value2&param1=value1 porque no importa el orden de los parámetros de consulta. Sin embargo, el filtro no coincide con https://project.example.com/any/path/here?param1=value1, ya que le falta param2=value2.

O y Y

Las etiquetas <data> fuera de una <uri-relative-filter-group> se usan con la operación OR, mientras que las etiquetas <data> dentro de una <uri-relative-filter-group> se usan con la operación AND.

Consulta el siguiente ejemplo:

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

El filtro coincide con las rutas que comienzan con /prefix O terminan con suffix.

En cambio, el siguiente ejemplo coincide con las rutas que comienzan con /prefix Y terminan con 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>

Como resultado, varios atributos path en el mismo <uri-relative-filter-group> no coinciden con nada:

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

Orden de declaración

Consulta el siguiente ejemplo:

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

El filtro coincide con el fragmento #fragment porque se encuentra una coincidencia antes de que se evalúe la regla de exclusión, pero los fragmentos como #fragment123 no coinciden.

Etiquetas hermanas

Las etiquetas <uri-relative-filter-group> trabajan junto con sus etiquetas <data> hermanas (es decir, etiquetas <data> que están fuera de <uri-relative-filter-group>, pero dentro del mismo <intent-filter>). Las etiquetas <uri-relative-filter-group> deben tener etiquetas <data> hermanas para funcionar correctamente, ya que los atributos de URI dependen mutuamente a nivel de <intent-filter>:

  • Si no se especifica un scheme para el filtro de intents, se ignoran todos los demás atributos de URI.
  • Si no se especifica un host para el filtro, se ignoran el atributo port y todos los atributos path*.

Los elementos secundarios <data> de un <intent-filter> se evalúan antes que cualquier etiqueta <uri-relative-filter-group>. Luego, las etiquetas <uri-relative-filter-group> se evalúan en orden, por ejemplo:

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

El filtro acepta https://project.example.com/path?query porque coincide con <data android:path="/path" />, que está fuera de la regla de exclusión <uri-relative-filter-group>.

Caso de uso común

Imagina que tienes el URI https://project.example.com/path, que deseas hacer coincidir con un Intent según la presencia o el valor de un parámetro de consulta. Para crear un filtro de intents que coincida con https://project.example.com/path y bloquee https://project.example.com/path?query, puedes probar lo siguiente:

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

De hecho, esto no funciona. El URI https://project.example.com/path?query coincide con la ruta /path, y la etiqueta <uri-relative-filter-group> permite partes extra cuando coincide.

Revisa el filtro de intents de la siguiente manera:

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

Este filtro funciona porque las reglas de bloqueo que prohíben los parámetros de consulta no vacíos se evalúan primero.

Para simplificar el código, cambia el comportamiento para permitir parámetros de consulta y bloquear URIs sin parámetros de consulta:

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

Caracteres con codificación de URI

Para hacer coincidir los URIs que contienen caracteres codificados en URI, escribe los caracteres sin procesar y sin codificar en el filtro, por ejemplo:

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

El filtro coincide con ?param=value! y ?param=value%21.

Sin embargo, si escribes caracteres codificados en el filtro de la siguiente manera:

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

El filtro no coincide con ?param=value! ni ?param=value%21.

Cantidad de elementos

Puedes colocar cualquier cantidad de elementos <uri-relative-filter-group> dentro de un <intent-filter>.

Recursos adicionales

Para obtener información sobre el funcionamiento de los filtros de intents, incluidas las reglas sobre cómo se comparan los objetos de intents con los filtros, consulta Intents y filtros de intents y Filtros de intents.

Para obtener información sobre <uri-relative-filter-group>, consulta UriRelativeFilterGroup y UriRelativeFilter.

atributos:
android:allow
Indica si este grupo de filtros relativos al URI es una regla de inclusión (permitir) en lugar de una regla de exclusión (bloqueo). El valor predeterminado es "true".
Valor Descripción
"true" (predeterminado) Si el grupo de filtros relativos del URI coincide, el filtro de intent coincide.
"false" Si el grupo de filtros relativos de URI coincide, el filtro de intent no coincide.
primera inclusión:
Nivel de API 35
consulta también:
<intent-filter>
<data>