<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 Intent precisas que podem incluir parâmetros de consulta de URI e fragmentos de URI. As regras podem ser de inclusão (permitir) ou de exclusão (bloqueio), dependendo do atributo android:allow. 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 filtro relativo ao URI precisa corresponder a uma parte do URI. Pode haver partes do URI que não são especificadas no grupo de filtro relativo do 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 filtro relativo ao URI está presente. O filtro também corresponde a 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 não tem param2=value2.

OR e AND

As tags <data> fora de uma <uri-relative-filter-group> são unidas por OR, enquanto as tags <data> dentro de uma <uri-relative-filter-group> são unidas por AND.

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.

Por outro lado, o próximo exemplo 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 atributos path 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ãs

As tags <uri-relative-filter-group> funcionam com as tags <data> irmãs, 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ãs para funcionar corretamente, porque os atributos do 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 atributo port e todos os atributos path* serão ignorados.

Os filhos <data> de um <intent-filter> são avaliados antes de qualquer tag <uri-relative-filter-group>. 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 ele corresponde a <data android:path="/path" />, que está fora da regra de exclusão <uri-relative-filter-group>.

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 URI https://project.example.com/path?query corresponde ao caminho /path, e a tag <uri-relative-filter-group> permite partes extras durante a correspondência.

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 bloqueie 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 por URI

Para corresponder a URIs que contêm caracteres codificados em URI, escreva os caracteres brutos 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 qualquer número de elementos <uri-relative-filter-group> 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
Indica se esse grupo de filtro relativo 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 filtro relativo ao URI corresponder, o filtro de intent vai corresponder
"false" Se o grupo de filtro relativo ao URI corresponder, o filtro de intent não vai corresponder
introduzido em:
Nível 35 da API
veja também:
<intent-filter>
<data>