<uri-relative-filter-group>

ไวยากรณ์:
<uri-relative-filter-group android:allow=["true" | "false"]>
  <data ... />
  ...
</uri-relative-filter-group>
มีอยู่ใน
<intent-filter>
อาจมีข้อมูลต่อไปนี้
<data>
description:
สร้างกฎการจับคู่ที่Intentแม่นยำซึ่งอาจรวมถึงพารามิเตอร์การค้นหา URI และ ส่วนย่อย URI กฎอาจเป็นกฎการรวม (อนุญาต) หรือกฎการยกเว้น (การบล็อก) ก็ได้ ขึ้นอยู่กับแอตทริบิวต์ android:allow กฎการจับคู่จะระบุโดยแอตทริบิวต์ path*, fragment* และ query* ขององค์ประกอบ <data> ที่มีอยู่

การจับคู่

หากต้องการจับคู่ 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>

ตัวกรองตรงกับ https://project.example.com/any/path/here?param1=value1&param2=value2&param3=value3 เนื่องจากทุกอย่างที่ระบุโดยกลุ่มตัวกรองแบบสัมพัทธ์ของ URI มีอยู่ ตัวกรองยัง ตรงกับ https://project.example.com/any/path/here?param2=value2&param1=value1 เนื่องจากลำดับของพารามิเตอร์การค้นหาไม่สำคัญ แต่ตัวกรองไม่ตรงกับ https://project.example.com/any/path/here?param1=value1 ซึ่ง ไม่มี param2=value2

OR และ AND

แท็ก <data> นอก <uri-relative-filter-group> จะใช้ OR ส่วนแท็ก <data> ภายใน <uri-relative-filter-group> จะใช้ 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>

ด้วยเหตุนี้ แอตทริบิวต์หลายรายการ path ใน <uri-relative-filter-group> เดียวกันจึงไม่ตรงกับรายการใดเลย

<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> ที่อยู่ในระดับเดียวกัน (นั่นคือแท็ก <data> ที่อยู่นอก <uri-relative-filter-group> แต่อยู่ใน <intent-filter> เดียวกัน) แท็ก <uri-relative-filter-group> ต้องมีแท็ก <data> ที่อยู่ในระดับเดียวกันจึงจะทำงานได้อย่างถูกต้อง เนื่องจากแอตทริบิวต์ URI มีความสัมพันธ์กันที่ระดับ <intent-filter>

  • หากไม่ได้ระบุ scheme สำหรับตัวกรอง Intent ระบบจะละเว้นแอตทริบิวต์ URI อื่นๆ ทั้งหมด
  • หากไม่ได้ระบุ host สำหรับตัวกรอง ระบบจะไม่สนใจแอตทริบิวต์ port และแอตทริบิวต์ path* ทั้งหมด

ระบบจะประเมิน<data> children ของ <intent-filter> ก่อนแท็ก <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>

Use Case ทั่วไป

สมมติว่าคุณมี URI https://project.example.com/path ซึ่งต้องการจับคู่กับ Intent โดยขึ้นอยู่กับการมีอยู่หรือค่าของพารามิเตอร์การค้นหา หากต้องการสร้างตัวกรอง 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> อนุญาตให้มีส่วนextra เมื่อจับคู่

แก้ไขตัวกรอง Intent ดังนี้

<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

จำนวนองค์ประกอบ

คุณวางองค์ประกอบ <uri-relative-filter-group> กี่รายการก็ได้ภายใน <intent-filter>

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเกี่ยวกับวิธีการทำงานของตัวกรอง Intent รวมถึงกฎเกี่ยวกับวิธีจับคู่ออบเจ็กต์ Intent กับตัวกรองได้ที่ Intent และตัวกรอง Intent และ ตัวกรอง Intent

ดูข้อมูลเกี่ยวกับ <uri-relative-filter-group> ได้ที่ UriRelativeFilterGroup และ UriRelativeFilter

แอตทริบิวต์
android:allow
ไม่ว่ากลุ่มตัวกรองแบบ URI สัมพัทธ์นี้จะเป็นกฎการรวม (อนุญาต) หรือกฎ การยกเว้น (การบล็อก) ค่าเริ่มต้นคือ "true"
ค่านิยม คำอธิบาย
"true" (ค่าเริ่มต้น) หากกลุ่มตัวกรองแบบ URI สัมพัทธ์ตรงกัน ตัวกรอง Intent จะตรงกัน
"false" หากกลุ่มตัวกรองแบบ URI สัมพัทธ์ตรงกัน ตัวกรอง Intent จะไม่ตรงกัน
เปิดตัวใน
ระดับ API 35
ดูเพิ่มเติม
<intent-filter>
<data>