<uri-relative-filter-group>

語法:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
包含於:
<intent-filter>
可包含:
<data>
說明:
建立精確的 Intent 比對規則,可包含 URI 查詢參數和 URI 片段。規則可以是納入 (允許) 或排除 (封鎖) 規則,具體取決於 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-relative-filter-group> 標記必須有同層的 <data> 標記才能正常運作,因為 URI 屬性在 <intent-filter> 層級相互依賴:

  • 如果未為意圖篩選器指定 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 級別 35
另請參閱:
<intent-filter>
<data>