Intent Filter คือคำประกาศใน AndroidManifest.xml ที่บอกระบบว่าคอมโพเนนต์ของแอปพลิเคชันสามารถจัดการกับอินเทนต์โดยนัย (implicit intent) ประเภทใดได้บ้าง ตาม คู่มือนักพัฒนา Android ฟิลเตอร์ประกอบด้วย action, category และ data ซึ่งระบบใช้เป็นพื้นฐานในการกำหนดเส้นทางการเรียกจากแอปพลิเคชันอื่นและเหตุการณ์ของระบบ การพัฒนา Android ใช้ Intent Filter เป็นกลไกหลักสำหรับการเชื่อมต่อแบบหลวม ๆ ระหว่างคอมโพเนนต์ของแอปพลิเคชันต่างๆ
ประเด็นสำคัญ
Intent Filter คือองค์ประกอบการกำหนดค่าของแอปพลิเคชัน Android ที่แจ้งระบบเกี่ยวกับความสามารถของคอมโพเนนต์ในการจัดการอินเทนต์โดยนัยบางประเภท แตกต่างจาก Intent แบบชัดแจ้งที่ระบุคลาสเฉพาะ Intent โดยนัยจะมีเพียงคำอธิบายของการกระทำที่ต้องการ และระบบจะค้นหาคอมโพเนนต์ที่เหมาะสมเองตามฟิลเตอร์ที่ลงทะเบียนไว้
ฟิลเตอร์ถูกประกาศภายในคอมโพเนนต์ — Activity, Service หรือ BroadcastReceiver — ในไฟล์ AndroidManifest.xml แต่ละฟิลเตอร์สามารถมีองค์ประกอบ action, category และ data ได้หลายรายการ คอมโพเนนต์สามารถมี Intent Filter ได้ไม่จำกัดจำนวน โดยแต่ละฟิลเตอร์อธิบายสถานการณ์การจัดการที่แตกต่างกัน
Intent Filter ใช้หลักการของ การเชื่อมต่อแบบหลวม ๆ ระหว่างคอมโพเนนต์ของแอปพลิเคชัน แอปพลิเคชัน A ไม่จำเป็นต้องรู้เกี่ยวกับการมีอยู่ของแอปพลิเคชัน B — มันเพียงส่ง Intent พร้อมคำอธิบายการกระทำ และระบบกำหนดเส้นทางตามฟิลเตอร์ กลไกนี้เป็นพื้นฐานของ Share Sheet, การเลือกเบราว์เซอร์ และการจัดการลิงก์ลึก
Intent แบบชัดแจ้งระบุคลาสคอมโพเนนต์เฉพาะเพื่อเริ่มต้น ใช้สำหรับการนำทางภายในแอปพลิเคชันเดียวเมื่อนักพัฒนารู้แน่ชัดว่า Activity ใดควรเปิด Intent โดยนัยมีเพียงคำอธิบายการกระทำ และคอมโพเนนต์ถูกกำหนดโดยระบบแบบไดนามิก
Intent Filter ทำงานเฉพาะกับ Intent โดยนัยเท่านั้น หาก Intent ระบุคลาสเฉพาะ ระบบจะละเว้นฟิลเตอร์ทั้งหมดและเริ่มต้นคอมโพเนนต์ที่ระบุโดยตรง ฟิลเตอร์จะถูกตรวจสอบเมื่อแก้ไขการเรียกโดยนัยเท่านั้น ทำให้เป็นองค์ประกอบสำคัญของการโต้ตอบระหว่างแอปพลิเคชัน
| ลักษณะ | Intent แบบชัดแจ้ง | Intent โดยนัย |
|---|---|---|
| คอมโพเนนต์ | ระบุอย่างชัดแจ้ง (className) | กำหนดโดยระบบ |
| Intent Filter | ไม่จำเป็น | จำเป็น |
| ตัวอย่าง | startActivity(Intent(this, ProfileActivity::class.java)) | Intent(ACTION_VIEW, Uri.parse(”https://example.com”)) |
| ความปลอดภัย | สูงกว่า (ไม่มีการสกัดกั้น) | ต่ำกว่า (อาจมีความขัดแย้ง) |
แต่ละ Intent Filter ประกอบด้วยสามกลุ่มองค์ประกอบ — action, category และ data — ซึ่งการรวมกันกำหนดว่า Intent ใดที่คอมโพเนนต์จะได้รับ ฟิลเตอร์ถือว่าตรงตามเงื่อนไขหาก Intent ตรงกับอย่างน้อยหนึ่งองค์ประกอบของแต่ละกลุ่ม
Action อธิบายการกระทำที่กำลังดำเนินการ — การดู การแก้ไข การส่ง Category เพิ่มบริบทการประมวลผลเพิ่มเติม — ตัวอย่างเช่น ความสามารถในการเริ่มจากเบราว์เซอร์ Data กำหนดรูปแบบของข้อมูลที่ถูกจัดการผ่าน URI หรือชนิด MIME
ตัวอย่าง Intent Filter สำหรับ Activity ที่เปิดลิงก์ไปยังโปรไฟล์ผู้ใช้ ฟิลเตอร์รวมองค์ประกอบทั้งสามกลุ่มเพื่อการกำหนดเส้นทางที่แม่นยำ
<activity android:name=".ProfileActivity">
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="profile" />
</intent-filter>
</activity>
โปรดทราบการระบุ category DEFAULT ที่จำเป็น — หากไม่มี ระบบจะไม่ส่ง Intent โดยนัยไปยังคอมโพเนนต์ หมวดหมู่ BROWSABLE จะถูกเพิ่มหากลิงก์ควรถูกจัดการจากเบราว์เซอร์
ลิงก์ลึกบน Android ถูกกำหนดค่าผ่าน Intent Filter ที่มี action VIEW และแท็ก data ที่ประกอบด้วยสคีมา โฮสต์ และพาธ เมื่อติดตามลิงก์เช่น myapp://profile/42 ระบบจะพบ Activity ที่มีฟิลเตอร์ตรงกันและเริ่มต้นด้วย URI ที่ส่งผ่าน สิ่งสำคัญคือต้องกำหนดค่า pathPrefix, pathPattern หรือ path อย่างถูกต้องเพื่อการจับคู่ที่แม่นยำ
เริ่มจาก Android 6 (API 23) มีการเพิ่มการรองรับ App Links — ลิงก์ลึกที่ผ่านการตรวจสอบผ่าน HTTPS App Links ใช้ Intent Filter เดียวกัน แต่มีการตรวจสอบโดเมนเพิ่มเติมผ่าน Digital Asset Links หลังจากการตรวจสอบ ระบบจะเปิดแอปพลิเคชันโดยอัตโนมัติโดยไม่ต้องมีกล่องโต้ตอบการเลือก
ตัวอย่างฟิลเตอร์สำหรับ App Link ที่มีการตรวจสอบผ่านลิงก์ HTTPS ในกรณีนี้ สคีมาจะเป็น https เสมอ และโฮสต์ตรงกับโดเมนที่ระบุใน Digital Asset Links
<intent-filter android:autoVerify="true">
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="example.com"
android:pathPrefix="/profile" />
</intent-filter>
แอตทริบิวต์ autoVerify บอกระบบให้ตรวจสอบ Digital Asset Links เมื่อติดตั้งแอปพลิเคชัน หากการตรวจสอบผ่านสำเร็จ แอปพลิเคชันจะกลายเป็นตัวจัดการเริ่มต้นโดยอัตโนมัติสำหรับโดเมนและพาธที่ระบุ
หลังจากที่ระบบเลือกคอมโพเนนต์เพื่อจัดการ Intent แล้ว นักพัฒนาจะต้องดึงข้อมูลจาก intent ที่เข้ามาภายในคอมโพเนนต์เป้าหมาย สำหรับ Activity ใช้เมธอด getIntent() ใน onCreate() สำหรับ BroadcastReceiver ใช้เมธอด onReceive() โดย Intent ถูกส่งเป็นพารามิเตอร์
การดึงข้อมูลรวมถึงการรับ action เพื่อกำหนดประเภทของการดำเนินการ, data สำหรับ URI และพารามิเตอร์ extra สำหรับข้อมูลเพิ่มเติม องค์ประกอบเหล่านี้อาจไม่มีอยู่ ดังนั้นการตรวจสอบ null จึงจำเป็นก่อนการใช้งาน
ตัวอย่างการจัดการลิงก์ลึกที่เข้ามาใน Activity ด้วยภาษา Kotlin โค้ดจะดึง URI จาก Intent และตัดสินใจเกี่ยวกับการนำทางตามโฮสต์และพาธ
class ProfileActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val uri = intent?.data
if (uri?.host == "profile") {
val userId = uri.lastPathSegment
loadProfile(userId)
}
}
}
แนะนำให้ใช้ ตัวดำเนินการ safe call เพื่อตรวจสอบ intent และ data เป็น null เนื่องจากแอคทิวิตีอาจถูกเริ่มต้นโดยไม่มีลิงก์ลึกเข้ามา คุณควรตรวจสอบ host และ pathSegment เป็น null ก่อนใช้งานในการนำทาง
หากมีหลายแอปพลิเคชันลงทะเบียน Intent Filter ที่ตรงกับ Intent โดยนัยเดียวกัน ระบบจะแสดงกล่องโต้ตอบการเลือกให้ผู้ใช้ ผู้ใช้สามารถเลือกแอปพลิเคชันสำหรับการใช้ครั้งเดียวหรือตั้งค่าตัวจัดการเริ่มต้น เริ่มจาก Android 10 กล่องโต้ตอบการเลือกจะแสดงเฉพาะในการเรียกครั้งแรก หลังจากนั้นระบบจะจำตัวเลือกของผู้ใช้
ในการจัดการลำดับความสำคัญ จะใช้แอตทริบิวต์ android:priority ในแท็ก intent-filter ยิ่งค่าสูง คอมโพเนนต์ยิ่งมีลำดับความสำคัญสูงขึ้นเมื่อแก้ไขความขัดแย้ง อย่างไรก็ตาม ลำดับความสำคัญไม่ทำงานสำหรับฟิลเตอร์จากแอปพลิเคชันต่างๆ — ในกรณีนี้ กล่องโต้ตอบการเลือกจะแสดงเสมอหากไม่มีแอปพลิเคชันใดถูกตั้งเป็นค่าเริ่มต้น
นักพัฒนาสามารถเรียกกล่องโต้ตอบการเลือกโดยทางโปรแกรมผ่าน Intent.createChooser() โดยส่ง Intent เป้าหมายและหัวเรื่อง สิ่งนี้มีประโยชน์เมื่อแอปพลิเคชันต้องการเสนอให้ผู้ใช้เลือกตัวจัดการอย่างชัดเจน แม้ว่าจะมีการตั้งค่าแอปพลิเคชันเริ่มต้นไว้แล้ว ตัวอย่างเช่น เมื่อส่งรูปภาพไปยังโซเชียลเน็ตเวิร์กผ่าน ACTION_SEND ด้วย createChooser รับประกันว่าจะแสดงกล่องโต้ตอบโดยไม่ขึ้นกับการตั้งค่าเริ่มต้น
หนึ่งในข้อผิดพลาดที่พบบ่อยที่สุดคือการไม่มีหมวดหมู่ DEFAULT ใน Intent Filter นักพัฒนาคัดลอกการกำหนดค่าจากตัวอย่างแต่ลืมเพิ่มหมวดหมู่นี้ ส่งผลให้ Activity ไม่ได้รับ Intent โดยนัย ระบบเพียงแค่มองไม่เห็นฟิลเตอร์สำหรับการเรียกโดยนัย แม้ว่า Intent แบบชัดแจ้งจะยังคงทำงาน
ข้อผิดพลาดทั่วไปที่สองคือการระบุ scheme ในแท็ก data ไม่ถูกต้องโดยไม่มี URI ที่สมบูรณ์ หากระบุเฉพาะสคีมาแต่ไม่ระบุโฮสต์ ฟิลเตอร์จะยอมรับลิงก์ทั้งหมดที่มีสคีมานี้จากทุกแหล่ง ซึ่งอาจนำไปสู่การเรียกที่ไม่พึงประสงค์จากแหล่งที่ไม่น่าเชื่อถือ ขอแนะนำให้ระบุอย่างน้อย scheme และ host เสมอ
ข้อผิดพลาดที่สามคือการไม่มีการตรวจสอบ null สำหรับ intent.data ในโค้ด Activity หาก Activity ถูกเริ่มต้นไม่ใช่ผ่านลิงก์ลึกแต่ด้วยวิธีมาตรฐานจากลอนเชอร์ Intent จะไม่มี URI การเข้าถึง intent.data โดยไม่ตรวจสอบทำให้เกิด NullPointerException และแอปพลิเคชันขัดข้อง ใช้ intent?.data?.toString() ร่วมกับตัวดำเนินการ safe call เสมอ
คำถามที่พบบ่อย
ใช่ หมวดหมู่ DEFAULT จำเป็นสำหรับการรับ Intent โดยนัย หากไม่มี ระบบจะไม่ส่งการเรียกโดยนัยไปยังคอมโพเนนต์ และ Intent Filter จะทำงานเฉพาะกับ Intent แบบชัดแจ้งซึ่งไม่ได้ตรวจสอบฟิลเตอร์อยู่แล้ว
ไม่มีข้อจำกัด Activity หนึ่งสามารถมี Intent Filter ได้จำนวนเท่าใดก็ได้ แต่ละฟิลเตอร์อธิบายสถานการณ์การจัดการที่แตกต่างกัน เช่น หนึ่งฟิลเตอร์สำหรับลิงก์ลึก อีกฟิลเตอร์สำหรับการจัดการไฟล์ ฟิลเตอร์ที่สามสำหรับ Share Sheet
Intent Filter คือกลไกทั่วไปสำหรับการจัดการ Intent โดยนัย App Link เป็นกรณีพิเศษของ Intent Filter ที่มีการตรวจสอบผ่าน Digital Asset Links ซึ่งกำหนดให้แอปพลิเคชันเป็นตัวจัดการเริ่มต้นโดยอัตโนมัติสำหรับลิงก์ HTTPS บนโดเมนที่ระบุ
ได้ Intent Filter สามารถประกาศได้ไม่เพียงสำหรับ Activity แต่ยังสำหรับ Service และ BroadcastReceiver ด้วย สำหรับ Service สิ่งนี้ช่วยให้เรียกใช้บริการพื้นหลังจากแอปพลิเคชันอื่นได้ สำหรับ BroadcastReceiver — รับข้อความกระจายเสียงของระบบ
ชนิด MIME ถูกระบุในแท็ก data ผ่านแอตทริบิวต์ mimeType ฟิลเตอร์กำหนดชนิดข้อมูลที่คอมโพเนนต์สามารถจัดการได้ — ตัวอย่างเช่น image/* สำหรับรูปภาพทั้งหมดหรือ text/plain สำหรับข้อความธรรมดาเท่านั้น ชนิด MIME สามารถรวมกับสคีมา URI ได้
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม