<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 と一致しません。param2=value2 が欠落しています。

「または」と「かつ」

<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" /> と一致するため、フィルタで受け入れられます。<data android:path="/path" /><uri-relative-filter-group> 除外ルールの範囲外です。

一般的なユースケース

たとえば、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>