<uri-relative-filter-group>

Sintaxe:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
contido em:
<intent-filter>
pode conter:
<data>
descrição:
Cria regras de correspondência precisas Intent que podem incluir parâmetros de consulta e fragmentos de URI. As regras podem ser de inclusão (permitir) ou exclusão (bloqueio) regras, dependendo do android:allow atributo. As regras de correspondência são especificadas pelos atributos path*, fragment* e query* dos elementos <data> contidos.

Correspondência

Para corresponder a um URI, cada parte do grupo de filtros relativos ao URI precisa corresponder a uma parte do URI. Pode haver partes do URI que não são especificadas no grupo de filtros relativos ao URI. Exemplo:

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

O filtro corresponde a https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3 porque tudo especificado pelo grupo de filtros relativos ao URI está presente. O filtro também corresponde https://project.example.com/any/path/here?param2=value2&param1=value1 porque a ordem dos parâmetros de consulta não importa. No entanto, o filtro não corresponde a https://project.example.com/any/path/here?param1=value1, que está faltando param2=value2.

OR e AND

<data> tags fora de um <uri-relative-filter-group> são ORed, enquanto <data> tags dentro de um <uri-relative-filter-group> são ANDed.

Veja o exemplo a seguir:

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

O filtro corresponde a caminhos que começam com /prefix OU terminam com suffix.

Em contraste, o exemplo a seguir corresponde a caminhos que começam com /prefix E terminam com 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, vários path atributos no mesmo <uri-relative-filter-group> não correspondem a 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>

Ordem de declaração

Veja o exemplo a seguir:

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

O filtro corresponde ao fragmento #fragment porque uma correspondência é encontrada antes que a regra de exclusão seja avaliada, mas fragmentos como #fragment123 não correspondem.

Tags irmãos

<uri-relative-filter-group> As tags <data> funcionam com as tags <data> irmãos (ou seja, tags <data> que estão fora do <uri-relative-filter-group>, mas dentro do mesmo <intent-filter>). As tags <uri-relative-filter-group> precisam ter tags <data> irmãos para funcionar corretamente, porque os atributos de URI são mutuamente dependentes no nível <intent-filter>:

  • Se um scheme não for especificado para o filtro de intent, todos os outros atributos de URI serão ignorados.
  • Se um host não for especificado para o filtro, o port atributo e todos os path* atributos serão ignorados.

Os filhos <data> de um <intent-filter> são avaliados antes de qualquer <uri-relative-filter-group> tags. Em seguida, as tags <uri-relative-filter-group> são avaliadas em ordem, por exemplo:

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

O filtro aceita https://project.example.com/path?query porque corresponde a <data android:path="/path" />, que está fora da <uri-relative-filter-group> regra de exclusão.

Caso de uso comum

Imagine que você tenha o URI https://project.example.com/path, que você quer corresponder a um Intent dependendo da presença ou do valor de um parâmetro de consulta. Para criar um filtro de intent que corresponda a https://project.example.com/path e bloqueie https://project.example.com/path?query, tente algo como:

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

Isso, na verdade, não funciona. O https://project.example.com/path?query URI corresponde ao caminho /path, e a <uri-relative-filter-group> tag permite extra partes quando está correspondendo.

Revise o filtro de intent da seguinte maneira:

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

Esse filtro funciona porque as regras de bloqueio que proíbem parâmetros de consulta não vazios são avaliadas primeiro.

Para simplificar o código, inverta o comportamento para permitir parâmetros de consulta e bloquear URIs sem 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 codificados em URI

Para corresponder a URIs que contêm caracteres codificados em URI, escreva os caracteres brutos e não codificados no filtro, por exemplo:

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

O filtro corresponde a ?param=value! e ?param=value%21.

No entanto, se você escrever caracteres codificados no filtro da seguinte maneira:

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

O filtro não corresponde a ?param=value! nem a ?param=value%21.

Número de elementos

Você pode colocar quantos <uri-relative-filter-group> elementos quiser dentro de um <intent-filter>.

Outros recursos

Para mais informações sobre como os filtros de intent funcionam, incluindo as regras de correspondência dos objetos de intent com os filtros, consulte Intents e filtros de intent e Filtros de intent.

Para informações sobre <uri-relative-filter-group>, consulte UriRelativeFilterGroup e UriRelativeFilter.

atributos:
android:allow
Se esse grupo de filtros relativos ao URI é uma regra de inclusão (permitir) em vez de uma regra de exclusão (bloqueio). O valor padrão é "true".
Valor Descrição
"true" (padrão) Se o grupo de filtros relativos ao URI corresponder, o filtro de intent vai corresponder
"false" Se o grupo de filtros relativos ao URI corresponder, o filtro de intent não vai corresponder
introduzido em:
Nível 35 da API
veja também:
<intent-filter>
<data>