<uri-relative-filter-group>

構文:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
上位の要素:
<intent-filter>
含めることのできる要素:
<data>
説明:
URI クエリ パラメータと URI フラグメントを含めることができる正確な Intent 照合ルールを作成します。ルールは、android:allow 属性に応じて、包含(許可)ルールまたは除外(ブロック)ルールにできます。一致ルールは、含まれている <data> 要素の path*fragment*query* 属性で指定されます。

マッチング問題

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>

URI 相対フィルタ グループで指定されたものがすべて存在するため、フィルタは https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3 と一致します。クエリ パラメータの順序は関係ないため、このフィルタは https://project.example.com/any/path/here?param2=value2&param1=value1 にも一致します。ただし、フィルタは https://project.example.com/any/path/here?param1=value1 と一致しません。https://project.example.com/any/path/here?param1=value1 には param2=value2 がありません。

OR と AND

<uri-relative-filter-group> の外側の <data> タグは OR 演算され、<uri-relative-filter-group> の内側の <data> タグは 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>

その結果、同じ <uri-relative-filter-group> 内の複数の path 属性は何も一致しません。

<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> タグ(つまり、<uri-relative-filter-group> の外側で同じ <intent-filter> の内側にある <data> タグ)と連携して動作します。 URI 属性は <intent-filter> レベルで相互に依存しているため、<uri-relative-filter-group> タグが正しく機能するには、兄弟の <data> タグが必要です。

  • インテント フィルタに対して scheme が指定されていない場合、他のすべての URI 属性が無視されます。
  • フィルタに対して host が指定されていない場合、port 属性とすべての path* 属性が無視されます。

<intent-filter><data> 子は、<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> 除外ルールの範囲外であるため、フィルタは https://project.example.com/path?query を受け入れます。

一般的なユースケース

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>

実際には、これは機能しません。https://project.example.com/path?query URI はパス /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 のどちらとも一致しません。

要素の数

<intent-filter> 内に任意の数の <uri-relative-filter-group> 要素を配置できます。

参考情報

インテント オブジェクトとフィルタのマッチング ルールなど、インテント フィルタの仕組みの詳細については、インテントとインテント フィルタ、およびインテント フィルタをご覧ください。

<uri-relative-filter-group> の詳細については、UriRelativeFilterGroupUriRelativeFilter をご覧ください。

属性:
android:allow
この URI 相対フィルタ グループが除外(ブロック)ルールではなく包含(許可)ルールであるかどうか。デフォルト値は "true" です。
説明
"true"(デフォルト) URI 相対フィルタ グループが一致する場合、インテント フィルタは一致します
"false" URI 相対フィルタ グループが一致する場合、インテント フィルタは一致しません
導入時の API レベル:
API レベル 35
関連項目:
<intent-filter>
<data>