เอกสารนี้อธิบายงาน NFC พื้นฐานที่คุณทำใน Android โดยจะอธิบายวิธีส่งและรับข้อมูล NFC ในรูปแบบของข้อความ NDEF รวมถึงอธิบาย API ของเฟรมเวิร์ก Android ที่รองรับฟีเจอร์เหล่านี้ ดูหัวข้อขั้นสูงเพิ่มเติม รวมถึงการอภิปรายเกี่ยวกับการทำงานกับข้อมูลที่ไม่ใช่ NDEF ได้ที่NFC ขั้นสูง
การอ่านข้อมูล NDEF จากแท็ก NFC จะได้รับการจัดการด้วยระบบการส่งแท็ก ซึ่งจะวิเคราะห์แท็ก NFC ที่ค้นพบ จัดหมวดหมู่ข้อมูลอย่างเหมาะสม และเริ่ม แอปพลิเคชันที่สนใจข้อมูลที่จัดหมวดหมู่ แอปพลิเคชันที่ต้องการจัดการแท็ก NFC ที่สแกนแล้วสามารถประกาศตัวกรอง Intent และ ขอจัดการข้อมูลได้
ระบบการเรียกใช้แท็ก
โดยปกติแล้ว อุปกรณ์ที่ใช้ Android จะมองหาแท็ก NFC เมื่อหน้าจอ ปลดล็อกอยู่ เว้นแต่จะปิดใช้ NFC ในเมนูการตั้งค่าของอุปกรณ์ เมื่ออุปกรณ์ที่ใช้ Android ค้นพบแท็ก NFC ลักษณะการทำงานที่ต้องการ คือให้กิจกรรมที่เหมาะสมที่สุดจัดการ Intent โดยไม่ต้องถามผู้ใช้ว่าจะใช้แอปพลิเคชันใด เนื่องจากอุปกรณ์จะสแกนแท็ก NFC ในระยะใกล้มาก การให้ผู้ใช้เลือกกิจกรรมด้วยตนเอง อาจบังคับให้ผู้ใช้ย้ายอุปกรณ์ออกจากแท็กและทำให้การเชื่อมต่อขาดตอน คุณควรพัฒนากิจกรรมให้จัดการเฉพาะแท็ก NFC ที่กิจกรรมของคุณสนใจเพื่อป้องกันไม่ให้ตัวเลือกกิจกรรมปรากฏ
Android มีระบบการส่งแท็กพิเศษที่วิเคราะห์แท็ก NFC ที่สแกน แยกวิเคราะห์ และพยายามค้นหาแอปพลิเคชันที่สนใจข้อมูลที่สแกน เพื่อช่วยให้คุณบรรลุเป้าหมายนี้ โดยมีวิธีการดังนี้
- แยกวิเคราะห์แท็ก NFC และค้นหาประเภท MIME หรือ URI ที่ระบุเพย์โหลดข้อมูล ในแท็ก
- การห่อหุ้มประเภท MIME หรือ URI และเพย์โหลดไว้ใน Intent ขั้นตอน 2 ขั้นตอนแรกนี้อธิบายไว้ในวิธีแมปแท็ก NFC กับประเภท MIME และ URI
- เริ่มกิจกรรมตามเจตนา ซึ่งอธิบายไว้ใน วิธีส่งแท็ก NFC ไปยังแอปพลิเคชัน
วิธีแมปแท็ก NFC กับประเภท MIME และ URI
ก่อนที่จะเริ่มเขียนแอปพลิเคชัน NFC คุณควรทำความเข้าใจแท็ก NFC ประเภทต่างๆ วิธีที่ระบบส่งแท็กแยกวิเคราะห์แท็ก NFC และการทำงานพิเศษที่ระบบส่งแท็ก ทำเมื่อตรวจพบข้อความ NDEF แท็ก NFC มีเทคโนโลยีที่หลากหลายและสามารถเขียนข้อมูลลงในแท็กได้หลายวิธี Android รองรับมาตรฐาน NDEF มากที่สุด ซึ่งกำหนดโดย NFC Forum
ข้อมูล NDEF จะห่อหุ้มอยู่ภายในข้อความ (NdefMessage) ซึ่งมีระเบียนอย่างน้อย 1 รายการ (NdefRecord) ระเบียน NDEF แต่ละรายการต้องมีรูปแบบที่ถูกต้องตามข้อกำหนดของประเภทระเบียนที่ต้องการสร้าง Android
ยังรองรับแท็กประเภทอื่นๆ ที่ไม่มีข้อมูล NDEF ซึ่งคุณสามารถใช้ได้โดยใช้
คลาสในแพ็กเกจ android.nfc.tech ดูข้อมูลเพิ่มเติม
เกี่ยวกับเทคโนโลยีเหล่านี้ได้ที่หัวข้อNFC ขั้นสูง การทำงานกับแท็กประเภทอื่นๆ เหล่านี้เกี่ยวข้องกับการเขียนสแต็กโปรโตคอลของคุณเองเพื่อสื่อสารกับแท็ก ดังนั้นเราขอแนะนำให้ใช้ NDEF เมื่อเป็นไปได้เพื่อความสะดวกในการพัฒนาและรองรับอุปกรณ์ที่ใช้ Android ได้สูงสุด
หมายเหตุ: หากต้องการดาวน์โหลดข้อกำหนด NDEF ทั้งหมด ให้ไปที่เว็บไซต์ข้อกำหนดและเอกสารการสมัครของ NFC Forum แล้วดู การสร้างระเบียน NDEF ประเภททั่วไปเพื่อดูตัวอย่างวิธี สร้างระเบียน NDEF
ตอนนี้คุณมีพื้นฐานเกี่ยวกับแท็ก NFC แล้ว ส่วนต่อไปนี้จะอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับวิธีที่
Android จัดการแท็กที่จัดรูปแบบ NDEF เมื่ออุปกรณ์ที่ใช้ Android สแกนแท็ก NFC ที่มีข้อมูลซึ่งจัดรูปแบบ NDEF
อุปกรณ์จะแยกวิเคราะห์ข้อความและพยายามหาประเภท MIME หรือ URI ที่ระบุ
ของข้อมูล โดยระบบจะอ่าน NdefRecord แรกภายใน NdefMessage เพื่อพิจารณาวิธีตีความข้อความ NDEF ทั้งหมด (ข้อความ NDEF อาจมีระเบียน NDEF หลายรายการ) ในข้อความ NDEF ที่มีรูปแบบถูกต้อง NdefRecord
แรกจะมีช่องต่อไปนี้
- TNF (รูปแบบชื่อประเภท) 3 บิต
- ระบุวิธีตีความฟิลด์ประเภทความยาวของตัวแปร ค่าที่ใช้ได้อธิบายไว้ในตารางที่ 1
- ประเภทความยาวตัวแปร
- อธิบายประเภทของระเบียน หากใช้
TNF_WELL_KNOWNให้ใช้ฟิลด์นี้เพื่อระบุคำจำกัดความประเภทระเบียน (RTD) ค่า RTD ที่ใช้ได้อธิบายไว้ในตารางที่ 2 - รหัสที่มีความยาวตัวแปร
- ตัวระบุที่ไม่ซ้ำกันสำหรับระเบียน ฟิลด์นี้ไม่ค่อยได้ใช้ แต่หากต้องการระบุแท็กที่ไม่ซ้ำ คุณสามารถสร้างรหัสสำหรับแท็กได้
- เพย์โหลดที่มีความยาวผันแปร
- เพย์โหลดข้อมูลจริงที่คุณต้องการอ่านหรือเขียน ข้อความ NDEF อาจมีระเบียน NDEF หลายรายการ ดังนั้นอย่าคิดว่าเพย์โหลดทั้งหมดอยู่ในระเบียน NDEF แรกของข้อความ NDEF
ระบบการส่งแท็กใช้ฟิลด์ TNF และประเภทเพื่อพยายามแมปประเภท MIME หรือ URI กับข้อความ NDEF หากสำเร็จ ระบบจะห่อหุ้มข้อมูลดังกล่าวไว้ภายใน ACTION_NDEF_DISCOVEREDIntent พร้อมกับเพย์โหลดจริง อย่างไรก็ตาม มีบางกรณีที่ระบบการส่งแท็กไม่สามารถระบุประเภทข้อมูลตามระเบียน NDEF แรกได้ กรณีนี้จะเกิดขึ้นเมื่อระบบจับคู่ข้อมูล NDEF กับประเภท MIME หรือ URI ไม่ได้ หรือเมื่อแท็ก NFC ไม่มีข้อมูล NDEF ตั้งแต่แรก ในกรณีดังกล่าว ระบบจะห่อหุ้มออบเจ็กต์ Tag ที่มีข้อมูลเกี่ยวกับเทคโนโลยีของแท็กและเพย์โหลดไว้ภายในอินเทนต์ ACTION_TECH_DISCOVERED แทน
ตารางที่ 1 อธิบายวิธีที่ระบบการส่งแท็กแมปฟิลด์ TNF และประเภท
กับประเภท MIME หรือ URI นอกจากนี้ยังอธิบายว่า TNF ใดที่จับคู่กับประเภท MIME หรือ URI ไม่ได้
ในกรณีเหล่านี้ ระบบการเรียกใช้แท็กจะกลับไปใช้ ACTION_TECH_DISCOVERED
เช่น หากระบบการเรียกใช้แท็กพบระเบียนประเภท TNF_ABSOLUTE_URI ระบบจะแมปฟิลด์ประเภทความยาวตัวแปรของระเบียนนั้น
เป็น URI ระบบการส่งแท็กจะแคปซูล URI นั้นในฟิลด์ข้อมูลของACTION_NDEF_DISCOVERED Intent พร้อมกับข้อมูลอื่นๆ เกี่ยวกับแท็ก
เช่น เพย์โหลด ในทางกลับกัน หากพบระเบียนประเภท TNF_UNKNOWN ระบบจะสร้าง Intent ที่ห่อหุ้มเทคโนโลยีของแท็กแทน
ตารางที่ 1 TNF ที่รองรับและการแมป
| รูปแบบชื่อประเภท (TNF) | การแมป |
|---|---|
TNF_ABSOLUTE_URI |
URI ตามช่องประเภท |
TNF_EMPTY |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
TNF_EXTERNAL_TYPE |
URI ตาม URN ในช่องประเภท ระบบจะเข้ารหัส URN ลงในฟิลด์ประเภท NDEF ใน
รูปแบบย่อ: <domain_name>:<service_name>
Android จะแมปค่านี้กับ URI ในรูปแบบต่อไปนี้
vnd.android.nfc://ext/<domain_name>:<service_name> |
TNF_MIME_MEDIA |
ประเภท MIME ตามช่องประเภท |
TNF_UNCHANGED |
ไม่ถูกต้องในระเบียนแรก จึงกลับไปใช้
ACTION_TECH_DISCOVERED |
TNF_UNKNOWN |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
TNF_WELL_KNOWN |
ประเภท MIME หรือ URI ขึ้นอยู่กับคำจำกัดความประเภทระเบียน (RTD) ซึ่งคุณตั้งค่าไว้ใน ช่องประเภท ดูข้อมูลเพิ่มเติมเกี่ยวกับ RTD ที่ใช้ได้และการแมปได้ที่ตารางที่ 2 |
ตารางที่ 2 RTD ที่รองรับสำหรับ TNF_WELL_KNOWN และการ แมป
| คำจำกัดความของประเภทระเบียน (RTD) | การแมป |
|---|---|
RTD_ALTERNATIVE_CARRIER |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
RTD_HANDOVER_CARRIER |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
RTD_HANDOVER_REQUEST |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
RTD_HANDOVER_SELECT |
เปลี่ยนกลับเป็น ACTION_TECH_DISCOVERED |
RTD_SMART_POSTER |
URI ตามการแยกวิเคราะห์เพย์โหลด |
RTD_TEXT |
ประเภท MIME ของ text/plain |
RTD_URI |
URI ตามเพย์โหลด |
วิธีส่งแท็ก NFC ไปยังแอปพลิเคชัน
เมื่อระบบการส่งแท็กสร้าง Intent ที่ห่อหุ้มแท็ก NFC และข้อมูลระบุตัวตนของแท็กเสร็จแล้ว ระบบจะส่ง Intent ไปยังแอปพลิเคชันที่สนใจซึ่งกรอง Intent หากมีแอปพลิเคชันมากกว่า 1 รายการที่จัดการ Intent ได้ ระบบจะแสดงตัวเลือกกิจกรรม เพื่อให้ผู้ใช้เลือกกิจกรรมได้ ระบบการเรียกใช้แท็กจะกำหนด Intent 3 รายการ ซึ่งแสดงตามลำดับความสำคัญจากสูงสุดไปต่ำสุด ดังนี้
-
ACTION_NDEF_DISCOVERED: Intent นี้ใช้เพื่อเริ่ม กิจกรรมเมื่อสแกนแท็กที่มีเพย์โหลด NDEF และเป็นประเภทที่ระบบรู้จัก นี่คือ Intent ที่มีลำดับความสำคัญสูงสุด และระบบการส่งแท็กจะพยายามเริ่มกิจกรรมด้วย Intent นี้ ก่อน Intent อื่นๆ ทุกครั้งที่เป็นไปได้หมายเหตุ: ตั้งแต่ Android 16 เป็นต้นไป การสแกนแท็ก NFC ที่จัดเก็บลิงก์ URL (เช่น รูปแบบ URI คือ "https://" หรือ "http://") จะทริกเกอร์
ACTION_VIEWIntent แทนACTION_NDEF_DISCOVEREDIntent ACTION_TECH_DISCOVERED: หากไม่มีกิจกรรมใดลงทะเบียนเพื่อจัดการ IntentACTION_NDEF_DISCOVEREDระบบการส่งแท็กจะพยายามเริ่มแอปพลิเคชันด้วย Intent นี้ นอกจากนี้ ระบบจะเริ่ม Intent นี้โดยตรง (โดยไม่ต้องเริ่มACTION_NDEF_DISCOVEREDก่อน) หากแท็กที่สแกน มีข้อมูล NDEF ที่ไม่สามารถแมปกับประเภท MIME หรือ URI หรือหากแท็กไม่มีข้อมูล NDEF แต่เป็นเทคโนโลยีแท็กที่รู้จักACTION_TAG_DISCOVERED: ระบบจะเริ่มความตั้งใจนี้ หากไม่มีกิจกรรมใดจัดการความตั้งใจACTION_NDEF_DISCOVEREDหรือACTION_TECH_DISCOVERED
ระบบการส่งแท็กทำงานในลักษณะพื้นฐานดังนี้
- พยายามเริ่มกิจกรรมด้วย Intent ที่สร้างขึ้นโดยระบบการส่งแท็ก
เมื่อแยกวิเคราะห์แท็ก NFC (ไม่ว่าจะเป็น
ACTION_NDEF_DISCOVEREDหรือACTION_TECH_DISCOVERED) - หากไม่มีตัวกรองกิจกรรมสำหรับ Intent นั้น ให้ลองเริ่มกิจกรรมด้วย Intent ที่มีลำดับความสำคัญต่ำที่สุดถัดไป (
ACTION_TECH_DISCOVEREDหรือACTION_TAG_DISCOVERED) จนกว่าแอปพลิเคชันจะกรอง Intent หรือจนกว่าระบบการส่งแท็กจะลอง Intent ที่เป็นไปได้ทั้งหมด - หากไม่มีตัวกรองแอปพลิเคชันสำหรับ Intent ใดๆ ให้ไม่ต้องดำเนินการใดๆ
ให้ใช้ข้อความ NDEF และACTION_NDEF_DISCOVERED Intent ทุกครั้งที่ทำได้ เนื่องจากเป็น Intent ที่เฉพาะเจาะจงที่สุดใน 3 รายการ ความตั้งใจนี้ช่วยให้คุณเริ่มแอปพลิเคชันได้ในเวลาที่เหมาะสมกว่าความตั้งใจอีก 2 อย่าง ซึ่งจะช่วยให้ผู้ใช้ได้รับประสบการณ์ที่ดีขึ้น
ขอสิทธิ์เข้าถึง NFC ในไฟล์ Manifest ของ Android
ก่อนที่จะเข้าถึงฮาร์ดแวร์ NFC ของอุปกรณ์และจัดการ Intent ของ NFC อย่างถูกต้อง ให้ประกาศรายการต่อไปนี้ในไฟล์ AndroidManifest.xml
- องค์ประกอบ NFC
<uses-permission>สำหรับเข้าถึงฮาร์ดแวร์ NFC<uses-permission android:name="android.permission.NFC" />
- SDK เวอร์ชันขั้นต่ำที่แอปพลิเคชันของคุณรองรับได้ API ระดับ 9 รองรับเฉพาะ
การส่งแท็กที่จำกัดผ่าน
ACTION_TAG_DISCOVEREDและให้สิทธิ์ เข้าถึงข้อความ NDEF ผ่านEXTRA_NDEF_MESSAGESเท่านั้น คุณจะเข้าถึงพร็อพเพอร์ตี้แท็กหรือการดำเนินการ I/O อื่นๆ ไม่ได้ API ระดับ 10 มีการรองรับการอ่าน/เขียนอย่างครอบคลุม รวมถึงการพุช NDEF ในเบื้องหน้า และ API ระดับ 14 มีเมธอดที่สะดวกเพิ่มเติมในการสร้างระเบียน NDEF<uses-sdk android:minSdkVersion="10"/> - องค์ประกอบ
uses-featureเพื่อให้แอปพลิเคชันของคุณปรากฏใน Google Play เฉพาะสำหรับอุปกรณ์ที่มีฮาร์ดแวร์ NFC เท่านั้น<uses-feature android:name="android.hardware.nfc" android:required="true" />
หากแอปพลิเคชันของคุณใช้ฟังก์ชัน NFC แต่ฟังก์ชันดังกล่าวไม่ได้มีความสำคัญต่อแอปพลิเคชัน คุณสามารถละเว้นองค์ประกอบ
uses-featureและตรวจสอบความพร้อมใช้งานของ NFC ที่รันไทม์ได้โดยตรวจสอบว่าgetDefaultAdapter()เป็นnullหรือไม่
กรอง Intent ของ NFC
หากต้องการเริ่มแอปพลิเคชันเมื่อมีการสแกนแท็ก NFC ที่คุณต้องการจัดการ แอปพลิเคชัน
สามารถกรอง Intent NFC อย่างใดอย่างหนึ่ง สองอย่าง หรือทั้งสามอย่างในไฟล์ Manifest ของ Android อย่างไรก็ตาม โดยปกติแล้วคุณ
มักจะต้องการกรองACTION_NDEF_DISCOVEREDเจตนาสำหรับ
การควบคุมเวลาที่แอปพลิเคชันของคุณเริ่มต้นมากที่สุด ACTION_TECH_DISCOVERED Intent เป็นการสำรองสำหรับ ACTION_NDEF_DISCOVERED เมื่อไม่มีตัวกรองแอปพลิเคชันสำหรับ
ACTION_NDEF_DISCOVERED หรือเมื่อเพย์โหลดไม่ใช่
NDEF การกรองสำหรับ ACTION_TAG_DISCOVERED มักจะเป็นหมวดหมู่ทั่วไปเกินไป
ที่จะใช้กรอง แอปพลิเคชันจำนวนมากจะกรอง ACTION_NDEF_DISCOVERED หรือ ACTION_TECH_DISCOVERED ก่อน ACTION_TAG_DISCOVERED ดังนั้นแอปพลิเคชันของคุณจึงมีโอกาสต่ำที่จะ
เริ่มต้น ACTION_TAG_DISCOVERED จะใช้เป็นทางเลือกสุดท้ายเท่านั้น
สำหรับแอปพลิเคชันในการกรองในกรณีที่ไม่มีแอปพลิเคชันอื่นติดตั้งไว้เพื่อจัดการ
ACTION_NDEF_DISCOVERED หรือเจตนา ACTION_TECH_DISCOVERED
เนื่องจากการติดตั้งใช้งานแท็ก NFC มีความหลากหลายและหลายครั้งที่อยู่นอกเหนือการควบคุมของคุณ จึงไม่สามารถทำได้เสมอไป ด้วยเหตุนี้ คุณจึงสามารถใช้ 2 Intent อื่นแทนได้เมื่อจำเป็น เมื่อคุณควบคุมประเภทของแท็กและข้อมูลที่เขียนได้ ขอแนะนําให้ใช้ NDEF เพื่อจัดรูปแบบแท็ก ส่วนต่อไปนี้จะอธิบายวิธีกรองตามประเภทความตั้งใจแต่ละประเภท
ACTION_NDEF_DISCOVERED
หากต้องการกรองACTION_NDEF_DISCOVEREDเจตนา ให้ประกาศ
ตัวกรองเจตนาพร้อมกับประเภทข้อมูลที่ต้องการกรอง ตัวอย่างต่อไปนี้จะกรอง ACTION_NDEF_DISCOVERED
Intent ที่มีประเภท MIME เป็น text/plain
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>
ตัวอย่างต่อไปนี้จะกรอง URI ในรูปแบบ
https://developer.android.com/index.html
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
ACTION_TECH_DISCOVERED
หากตัวกรองกิจกรรมสำหรับเจตนา ACTION_TECH_DISCOVERED
คุณต้องสร้างไฟล์ทรัพยากร XML ที่ระบุเทคโนโลยีที่กิจกรรมรองรับ
ภายในชุด tech-list ระบบจะพิจารณากิจกรรมของคุณว่าตรงกันหากtech-listชุดเป็นส่วนย่อยของเทคโนโลยีที่แท็กรองรับ ซึ่งคุณจะได้รับโดยการเรียกใช้ getTechList()
เช่น หากแท็กที่สแกนรองรับ MifareClassic, NdefFormatable และ NfcA ชุดtech-listของคุณต้องระบุเทคโนโลยีทั้ง 3 อย่าง 2 อย่าง หรือ 1 อย่าง (และไม่มีอย่างอื่น) เพื่อให้ระบบจับคู่กิจกรรมของคุณได้
ตัวอย่างต่อไปนี้จะกำหนดเทคโนโลยีทั้งหมด คุณต้องนำแท็กที่ไม่รองรับออก
โดยแท็ก NFC บันทึกไฟล์นี้ (คุณจะตั้งชื่อไฟล์ว่าอะไรก็ได้) ในโฟลเดอร์ <project-root>/res/xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech> <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
นอกจากนี้ คุณยังระบุชุด tech-list ได้หลายชุดด้วย ระบบจะพิจารณาtech-list
แต่ละชุดแยกกัน และจะถือว่ากิจกรรมของคุณตรงกันหากtech-listชุดใดชุดหนึ่ง
เป็นส่วนย่อยของเทคโนโลยีที่ getTechList() แสดงผล ซึ่งจะให้ความหมายของ AND และ OR
สำหรับการจับคู่เทคโนโลยี ตัวอย่างต่อไปนี้ตรงกับแท็กที่รองรับเทคโนโลยี
NfcA และ Ndef หรือรองรับเทคโนโลยี NfcB และ Ndef
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> </resources>
ในไฟล์ AndroidManifest.xml ให้ระบุไฟล์ทรัพยากรที่คุณเพิ่งสร้าง
ในองค์ประกอบ <meta-data> ภายในองค์ประกอบ <activity>
เช่นเดียวกับในตัวอย่างต่อไปนี้
<activity> ... <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> ... </activity>
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทำงานกับเทคโนโลยีแท็กและACTION_TECH_DISCOVEREDเจตนาได้ที่การทำงานกับเทคโนโลยีแท็กที่รองรับในเอกสาร NFC ขั้นสูง
ACTION_TAG_DISCOVERED
หากต้องการกรองสำหรับ ACTION_TAG_DISCOVERED ให้ใช้ตัวกรอง Intent ต่อไปนี้
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
ACTION_VIEW
ตั้งแต่ Android 16 เป็นต้นไป การสแกนแท็ก NFC ที่จัดเก็บลิงก์ URL จะทริกเกอร์ Intent ACTION_VIEW หากต้องการกรอง ACTION_VIEW
โปรดดูthis ใช้ Android app links เพื่อเปิดแอปสำหรับ URL
รับข้อมูลจาก Intent
หากกิจกรรมเริ่มต้นเนื่องจาก Intent ของ NFC คุณจะได้รับข้อมูลเกี่ยวกับแท็ก NFC ที่สแกนจาก Intent Intent อาจมีส่วนเสริมต่อไปนี้ ขึ้นอยู่กับแท็กที่สแกน
EXTRA_TAG(ต้องระบุ): ออบเจ็กต์Tagที่แสดงแท็กที่สแกนEXTRA_NDEF_MESSAGES(ไม่บังคับ): อาร์เรย์ของข้อความ NDEF ที่แยกวิเคราะห์จากแท็ก ต้องระบุข้อมูลเพิ่มเติมนี้ใน เจตนาACTION_NDEF_DISCOVEREDEXTRA_ID(ไม่บังคับ): รหัสระดับต่ำของแท็ก
หากต้องการรับข้อมูลเพิ่มเติมเหล่านี้ ให้ตรวจสอบว่ากิจกรรมของคุณเปิดตัวด้วยเจตนา NFC อย่างใดอย่างหนึ่งเพื่อให้แน่ใจว่ามีการสแกนแท็ก จากนั้นรับข้อมูลเพิ่มเติมจากเจตนา ตัวอย่างต่อไปนี้จะตรวจสอบ ACTION_NDEF_DISCOVERED
Intent และรับข้อความ NDEF จาก Intent Extra
Kotlin
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) ... if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages -> val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage } // Process the messages array. ... } } }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); ... if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages != null) { NdefMessage[] messages = new NdefMessage[rawMessages.length]; for (int i = 0; i < rawMessages.length; i++) { messages[i] = (NdefMessage) rawMessages[i]; } // Process the messages array. ... } } }
หรือคุณจะรับออบเจ็กต์ Tag จาก Intent ก็ได้ ซึ่งจะมีเพย์โหลดและช่วยให้คุณแจงนับเทคโนโลยีของแท็กได้
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
สร้างระเบียน NDEF ประเภททั่วไป
ส่วนนี้จะอธิบายวิธีสร้างระเบียน NDEF ประเภทที่พบบ่อยเพื่อช่วยคุณเมื่อเขียนไปยัง
แท็ก NFC ตั้งแต่ Android 4.0 (API ระดับ 14) เป็นต้นไป คุณจะใช้เมธอด
createUri() เพื่อช่วยสร้างระเบียน URI โดยอัตโนมัติได้ ตั้งแต่ Android 4.1 (API ระดับ 16) เป็นต้นไป
createExternal()
และ createMime() จะพร้อมใช้งานเพื่อช่วยคุณสร้าง
ระเบียน NDEF ของ MIME และประเภทภายนอก ใช้วิธีการช่วยเหล่านี้ทุกครั้งที่เป็นไปได้เพื่อหลีกเลี่ยงข้อผิดพลาด
เมื่อสร้างระเบียน NDEF ด้วยตนเอง
ส่วนนี้ยังอธิบายวิธีสร้าง ตัวกรอง Intent ที่เกี่ยวข้องสำหรับระเบียนด้วย ตัวอย่างระเบียน NDEF ทั้งหมดนี้ควรอยู่ในระเบียน NDEF แรกของข้อความ NDEF ที่คุณเขียนลงในแท็ก
TNF_ABSOLUTE_URI
หมายเหตุ: เราขอแนะนำให้คุณใช้ประเภท RTD_URI แทน TNF_ABSOLUTE_URI เนื่องจากมีประสิทธิภาพมากกว่า
คุณสร้างระเบียน TNF_ABSOLUTE_URI NDEF ได้ด้วยวิธีต่อไปนี้
Kotlin
val uriRecord = ByteArray(0).let { emptyByteArray -> NdefRecord( TNF_ABSOLUTE_URI, "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")), emptyByteArray, emptyByteArray ) }
Java
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI , "https://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")), new byte[0], new byte[0]);
ตัวกรอง Intent สำหรับระเบียน NDEF ก่อนหน้าจะมีลักษณะดังนี้
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
TNF_MIME_MEDIA
คุณสร้างระเบียน TNF_MIME_MEDIA NDEF ได้ด้วยวิธีต่อไปนี้
การใช้วิธี createMime()
Kotlin
val mimeRecord = NdefRecord.createMime( "application/vnd.com.example.android.beam", "Beam me up, Android".toByteArray(Charset.forName("US-ASCII")) )
Java
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
การสร้าง NdefRecord ด้วยตนเอง
Kotlin
val mimeRecord = Charset.forName("US-ASCII").let { usAscii -> NdefRecord( NdefRecord.TNF_MIME_MEDIA, "application/vnd.com.example.android.beam".toByteArray(usAscii), ByteArray(0), "Beam me up, Android!".toByteArray(usAscii) ) }
Java
NdefRecord mimeRecord = new NdefRecord( NdefRecord.TNF_MIME_MEDIA , "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
ตัวกรอง Intent สำหรับระเบียน NDEF ก่อนหน้าจะมีลักษณะดังนี้
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.com.example.android.beam" /> </intent-filter>
TNF_WELL_KNOWN ที่มี RTD_TEXT
คุณสร้างระเบียน TNF_WELL_KNOWN NDEF ได้โดยทำดังนี้
Kotlin
fun createTextRecord(payload: String, locale: Locale, encodeInUtf8: Boolean): NdefRecord { val langBytes = locale.language.toByteArray(Charset.forName("US-ASCII")) val utfEncoding = if (encodeInUtf8) Charset.forName("UTF-8") else Charset.forName("UTF-16") val textBytes = payload.toByteArray(utfEncoding) val utfBit: Int = if (encodeInUtf8) 0 else 1 shl 7 val status = (utfBit + langBytes.size).toChar() val data = ByteArray(1 + langBytes.size + textBytes.size) data[0] = status.toByte() System.arraycopy(langBytes, 0, data, 1, langBytes.size) System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size) return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), data) }
Java
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; }
ตัวกรอง Intent สำหรับระเบียน NDEF ก่อนหน้าจะมีลักษณะดังนี้
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
TNF_WELL_KNOWN ที่มี RTD_URI
คุณสร้างระเบียน TNF_WELL_KNOWN NDEF ได้ด้วยวิธีต่อไปนี้
การใช้วิธี createUri(String)
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
การใช้วิธี createUri(Uri)
Kotlin
val rtdUriRecord2 = Uri.parse("https://example.com").let { uri -> NdefRecord.createUri(uri) }
Java
Uri uri = Uri.parse("https://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
การสร้าง NdefRecord ด้วยตนเอง
Kotlin
val uriField = "example.com".toByteArray(Charset.forName("US-ASCII")) val payload = ByteArray(uriField.size + 1) //add 1 for the URI Prefix payload [0] = 0x01 //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.size) //appends URI to payload val rtdUriRecord = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, ByteArray(0), payload)
Java
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix payload[0] = 0x01; //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord( NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
ตัวกรอง Intent สำหรับระเบียน NDEF ก่อนหน้าจะมีลักษณะดังนี้
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="example.com" android:pathPrefix="" /> </intent-filter>
TNF_EXTERNAL_TYPE
คุณสร้างระเบียน NDEF TNF_EXTERNAL_TYPE ได้ด้วยวิธีต่อไปนี้
การใช้วิธี createExternal()
Kotlin
var payload: ByteArray //assign to your data val domain = "com.example" //usually your app's package name val type = "externalType" val extRecord = NdefRecord.createExternal(domain, type, payload)
Java
byte[] payload; //assign to your data String domain = "com.example"; //usually your app's package name String type = "externalType"; NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
การสร้าง NdefRecord ด้วยตนเอง
Kotlin
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Java
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
ตัวกรอง Intent สำหรับระเบียน NDEF ก่อนหน้าจะมีลักษณะดังนี้
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="vnd.android.nfc" android:host="ext" android:pathPrefix="/com.example:externalType"/> </intent-filter>
ใช้ TNF_EXTERNAL_TYPE สำหรับการติดตั้งใช้งานแท็ก NFC ทั่วไปมากขึ้นเพื่อรองรับทั้งอุปกรณ์ที่ใช้และไม่ได้ใช้ระบบปฏิบัติการ Android ได้ดียิ่งขึ้น
หมายเหตุ: URN สำหรับ TNF_EXTERNAL_TYPE มีรูปแบบ Canonical ดังนี้
urn:nfc:ext:example.com:externalType อย่างไรก็ตาม ข้อกำหนด RTD ของ NFC Forum
ระบุว่าต้องละเว้นส่วน urn:nfc:ext: ของ URN จาก
ระเบียน NDEF ดังนั้นสิ่งที่คุณต้องระบุคือโดเมน (example.com ในตัวอย่าง)
และประเภท (externalType ในตัวอย่าง) โดยคั่นด้วยเครื่องหมายโคลอน
เมื่อส่ง TNF_EXTERNAL_TYPE Android จะแปลง URN ของ urn:nfc:ext:example.com:externalType
เป็น URI ของ vnd.android.nfc://ext/example.com:externalType ซึ่งเป็นสิ่งที่
ตัวกรอง Intent ในตัวอย่างประกาศ
บันทึกแอปพลิเคชัน Android
Android Application Record (AAR) ซึ่งเปิดตัวใน Android 4.0 (API ระดับ 14) ช่วยให้มั่นใจได้มากขึ้น ว่าแอปพลิเคชันจะเริ่มทำงานเมื่อมีการสแกนแท็ก NFC AAR มีชื่อแพ็กเกจ ของแอปพลิเคชันที่ฝังอยู่ภายในระเบียน NDEF คุณสามารถเพิ่ม AAR ลงในระเบียน NDEF ของข้อความ NDEF ได้ เนื่องจาก Android จะค้นหา AAR ในข้อความ NDEF ทั้งหมด หากพบ AAR ระบบจะเริ่ม แอปพลิเคชันตามชื่อแพ็กเกจภายใน AAR หากไม่มีแอปพลิเคชันในอุปกรณ์ ระบบจะเปิด Google Play เพื่อดาวน์โหลดแอปพลิเคชัน
AAR มีประโยชน์หากคุณต้องการป้องกันไม่ให้แอปพลิเคชันอื่นๆ กรองตามความตั้งใจเดียวกัน และ อาจจัดการแท็กที่เฉพาะเจาะจงซึ่งคุณได้ติดตั้งใช้งาน AAR รองรับเฉพาะที่ระดับแอปพลิเคชันเนื่องจากข้อจํากัดของชื่อแพ็กเกจ และไม่รองรับที่ระดับกิจกรรมเหมือนกับการกรอง Intent หากต้องการจัดการ Intent ที่ระดับกิจกรรม ให้ใช้ตัวกรอง Intent
หากแท็กมี AAR ระบบการเรียกใช้แท็กจะเรียกใช้ในลักษณะต่อไปนี้
- ลองเริ่มกิจกรรมโดยใช้ตัวกรอง Intent ตามปกติ หากกิจกรรมที่ตรงกับ ความตั้งใจตรงกับ AAR ด้วย ให้เริ่มกิจกรรม
- หากกิจกรรมที่กรอง Intent ไม่ตรงกับ AAR หากมีกิจกรรมหลายรายการที่จัดการ Intent ได้ หรือหากไม่มีกิจกรรมใดจัดการ Intent ให้เริ่มแอปพลิเคชันที่ระบุโดย AAR
- หากไม่มีแอปพลิเคชันใดที่สามารถเริ่มต้นด้วย AAR ให้ไปที่ Google Play เพื่อดาวน์โหลด แอปพลิเคชันตาม AAR
หมายเหตุ: คุณสามารถลบล้าง AAR และระบบการส่งเจตนาด้วยระบบการส่งในเบื้องหน้า ซึ่งจะช่วยให้กิจกรรมในเบื้องหน้ามีลำดับความสำคัญเมื่อตรวจพบแท็ก NFC วิธีนี้กำหนดให้กิจกรรมต้องอยู่ในเบื้องหน้าเพื่อลบล้าง AAR และระบบการส่งต่อ Intent
หากยังต้องการกรองแท็กที่สแกนซึ่งไม่มี AAR คุณสามารถประกาศ ตัวกรอง Intent ได้ตามปกติ ซึ่งจะมีประโยชน์หากแอปพลิเคชันของคุณสนใจแท็กอื่นๆ ที่ไม่มี AAR เช่น คุณอาจต้องการรับประกันว่าแอปพลิเคชันจะจัดการแท็กที่เป็นกรรมสิทธิ์ที่คุณติดตั้งใช้งาน รวมถึงแท็กทั่วไปที่บุคคลที่สามติดตั้งใช้งาน โปรดทราบว่า AAR ใช้ได้กับอุปกรณ์ Android 4.0 ขึ้นไป ดังนั้นเมื่อติดตั้งใช้งานแท็ก คุณอาจต้องใช้ AAR ร่วมกับประเภท MIME/URI เพื่อรองรับอุปกรณ์ที่หลากหลายที่สุด นอกจากนี้ เมื่อติดตั้งใช้งานแท็ก NFC ให้พิจารณาว่าคุณต้องการเขียนแท็ก NFC อย่างไรเพื่อเปิดใช้ การรองรับอุปกรณ์ส่วนใหญ่ (อุปกรณ์ที่ใช้ Android และอุปกรณ์อื่นๆ) คุณทำได้โดย กำหนดประเภท MIME หรือ URI ที่ค่อนข้างไม่ซ้ำกันเพื่อให้แอปพลิเคชันแยกความแตกต่างได้ง่ายขึ้น
Android มี API ที่ใช้งานง่ายสำหรับสร้าง AAR
createApplicationRecord() สิ่งที่คุณต้องทำคือฝัง AAR ไว้ที่ใดก็ได้ใน NdefMessage คุณไม่ต้องการ
ใช้ระเบียนแรกของ NdefMessage เว้นแต่ AAR จะเป็นระเบียนเดียวใน NdefMessage เนื่องจากระบบ Android
จะตรวจสอบระเบียนแรกของ NdefMessage เพื่อกำหนดประเภท MIME หรือ
URI ของแท็ก ซึ่งใช้เพื่อสร้าง Intent ให้แอปพลิเคชันกรอง โค้ดต่อไปนี้
แสดงวิธีสร้าง AAR
Kotlin
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Java
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )
รายการที่อนุญาตของแอปสำหรับการสแกนแท็ก NFC
ตั้งแต่ Android 16 เป็นต้นไป ผู้ใช้จะได้รับการแจ้งเตือนเมื่อแอปได้รับ Intent NFC แรกเพื่อสแกนแท็ก NFC ผู้ใช้จะมีตัวเลือกในการไม่อนุญาตให้แอปสแกนหาแท็ก NFC อีกต่อไปในการแจ้งเตือน
- แอปจะตรวจสอบได้ว่าผู้ใช้ได้อนุญาตให้แอปสแกนแท็ก NFC หรือไม่โดยใช้
NfcAdapter.isTagIntentAllowed() - แอปสามารถแจ้งให้ผู้ใช้อนุญาตการสแกนแท็ก NFC อีกครั้งได้โดยการส่ง Intent
ACTION_CHANGE_TAG_INTENT_PREFERENCE
หมายเหตุ: คุณเข้าถึงรายการที่อนุญาตของแอปสแกนแท็ก NFC ได้ในส่วนSettings > Apps > Special app access > Launch via NFC