<uri-relative-filter-group>

Syntaxe :
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
Contenu dans :
<intent-filter>
Peut contenir :
<data>
Description :
Crée des règles de correspondance Intent précises pouvant inclure des paramètres de requête URI et des fragments d'URI. Les règles peuvent être des règles d'inclusion (autorisation) ou d'exclusion (blocage), en fonction de l'attribut android:allow. Les règles de correspondance sont spécifiées par les attributs path*, fragment* et query* des éléments <data> contenus.

Mise en correspondance

Pour correspondre à un URI, chaque partie du groupe de filtres relatifs à l'URI doit correspondre à une partie de l'URI. Certaines parties de l'URI peuvent ne pas être spécifiées dans le groupe de filtres relatif à l'URI. Exemple :

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

Le filtre correspond à https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3, car tout ce qui est spécifié par le groupe de filtres relatif à l'URI est présent. Le filtre correspond également à https://project.example.com/any/path/here?param2=value2&param1=value1, car l'ordre des paramètres de requête n'a pas d'importance. Toutefois, le filtre ne correspond pas à https://project.example.com/any/path/here?param1=value1, qui ne contient pas param2=value2.

OU et AND

Les balises <data> en dehors d'un <uri-relative-filter-group> sont associées à l'opérateur OR, tandis que les balises <data> à l'intérieur d'un <uri-relative-filter-group> sont associées à l'opérateur AND.

Prenons l'exemple suivant :

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

Le filtre correspond aux chemins d'accès commençant par /prefix OU se terminant par suffix.

À l'inverse, l'exemple suivant correspond aux chemins commençant par /prefix ET se terminant par 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>

Par conséquent, plusieurs attributs path dans le même <uri-relative-filter-group> ne correspondent à rien:

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

Ordre de déclaration

Prenons l'exemple suivant :

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

Le filtre correspond au fragment #fragment, car une correspondance est trouvée avant l'évaluation de la règle d'exclusion, mais les fragments tels que #fragment123 ne correspondent pas.

Balises sœurs

Les balises <uri-relative-filter-group> fonctionnent avec leurs balises <data> sœurs (c'est-à-dire les balises <data> situées en dehors de <uri-relative-filter-group>, mais dans le même <intent-filter>). Les balises <uri-relative-filter-group> doivent avoir des balises <data> sœurs pour fonctionner correctement, car les attributs URI sont mutuellement dépendants au niveau de <intent-filter>:

  • Si aucun élément scheme n'est spécifié pour le filtre d'intent, tous les autres attributs d'URI sont ignorés.
  • Si aucun élément host n'est spécifié pour le filtre, l'attribut port et tous les attributs path* sont ignorés.

Les enfants <data> d'un <intent-filter> sont évalués avant toute balise <uri-relative-filter-group>. Les balises <uri-relative-filter-group> sont ensuite évaluées dans l'ordre, par exemple:

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

Le filtre accepte https://project.example.com/path?query, car il correspond à <data android:path="/path" />, qui n'est pas inclus dans la règle d'exclusion <uri-relative-filter-group>.

Cas d'utilisation courant

Imaginons que vous disposiez de l'URI https://project.example.com/path, que vous souhaitez faire correspondre à un Intent en fonction de la présence ou de la valeur d'un paramètre de requête. Pour créer un filtre d'intent correspondant à https://project.example.com/path et bloquant https://project.example.com/path?query, vous pouvez essayer ceci:

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

En réalité, cela ne fonctionne pas. L'URI https://project.example.com/path?query correspond au chemin /path, et la balise <uri-relative-filter-group> autorise des parties supplémentaires lorsqu'elle est en correspondance.

Modifiez le filtre d'intent comme suit:

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

Ce filtre fonctionne, car les règles de blocage qui interdisent les paramètres de requête non vides sont évaluées en premier.

Pour simplifier le code, inversez le comportement pour autoriser les paramètres de requête et bloquer les URI sans paramètres de requête:

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

Caractères encodés en URI

Pour faire correspondre les URI contenant des caractères encodés en URI, écrivez les caractères bruts non encodés dans le filtre, par exemple:

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

Le filtre correspond à ?param=value! et ?param=value%21.

Toutefois, si vous écrivez des caractères encodés dans le filtre comme suit:

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

Le filtre ne correspond ni à ?param=value!, ni à ?param=value%21.

Nombre d'éléments

Vous pouvez placer autant d'éléments <uri-relative-filter-group> que vous le souhaitez dans un élément <intent-filter>.

Ressources supplémentaires

Pour en savoir plus sur le fonctionnement des filtres d'intent, y compris les règles de mise en correspondance des objets d'intent, consultez Intents et filtres d'intent et Filtres d'intent.

Pour en savoir plus sur <uri-relative-filter-group>, consultez UriRelativeFilterGroup et UriRelativeFilter.

Attributs :
android:allow
Indique si ce groupe de filtres relatif à l'URI est une règle d'inclusion (autorisation) plutôt qu'une règle d'exclusion (blocage). La valeur par défaut est "true".
Valeur Description
"true" (par défaut) Si le groupe de filtres relatif à l'URI correspond, le filtre d'intent correspond
"false" Si le groupe de filtres relatif à l'URI correspond, le filtre d'intent ne correspond pas
Première apparition :
Niveau d'API 35
Voir aussi :
<intent-filter>
<data>