<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>ย่อยของ<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>

กรณีการใช้งานทั่วไป

สมมติว่าคุณมี 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>

แต่วิธีนี้ไม่ได้ผล URI https://project.example.com/path?query จับคู่กับเส้นทาง /path และแท็ก <uri-relative-filter-group> อนุญาตให้มีชิ้นส่วนเพิ่มเติมเมื่อทำการจับคู่

แก้ไขตัวกรอง 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>