เอกสารนี้อธิบายงานพื้นฐานของ 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 แมปกับประเภทและ URI ของ MIME
ก่อนเริ่มเขียนแอปพลิเคชัน NFC คุณควรทำความเข้าใจแท็ก NFC ประเภทต่างๆ, วิธีที่ระบบส่งแท็กแยกวิเคราะห์แท็ก NFC และการดำเนินการพิเศษที่ระบบส่งแท็กทำเมื่อตรวจพบข้อความ NDEF แท็ก NFC มีเทคโนโลยีมากมายให้เลือก และสามารถเขียนข้อมูลลงในแท็ก NFC ได้หลายวิธี Android รองรับมาตรฐาน NDEF มากที่สุด ซึ่งกำหนดโดย NFC Forum
ข้อมูล NDEF รวมอยู่ในข้อความ (NdefMessage
) ที่มีระเบียนอย่างน้อย 1 รายการ (NdefRecord
) ระเบียน NDEF แต่ละรายการต้องมีรูปแบบที่ถูกต้องตามข้อกำหนดของประเภทระเบียนที่คุณต้องการสร้าง Android ยังรองรับแท็กประเภทอื่นๆ ที่ไม่มีข้อมูล NDEF ซึ่งคุณสามารถใช้งานโดยใช้คลาสในแพ็กเกจ android.nfc.tech
ดูข้อมูลเพิ่มเติมเกี่ยวกับเทคโนโลยีเหล่านี้ได้ที่หัวข้อ NFC ขั้นสูง การใช้แท็กประเภทอื่นๆ เหล่านี้เกี่ยวข้องกับการเขียนสแต็กโปรโตคอลของคุณเองเพื่อสื่อสารกับแท็ก เราจึงขอแนะนำให้ใช้ NDEF เมื่อเป็นไปได้เพื่อให้การพัฒนาง่ายขึ้นและรองรับอุปกรณ์ที่ทำงานด้วยระบบ Android ได้สูงสุด
หมายเหตุ: หากต้องการดาวน์โหลดข้อกำหนด NDEF ที่สมบูรณ์ ให้ไปที่เว็บไซต์ข้อกำหนดเฉพาะของฟอรัม NFC และเอกสารแอปพลิเคชัน และดูการสร้างระเบียน 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 หากทําสําเร็จ ระบบจะรวมข้อมูลดังกล่าวไว้ใน Intent ACTION_NDEF_DISCOVERED
พร้อมกับเพย์โหลดจริง อย่างไรก็ตาม อาจมีกรณีที่ระบบส่งแท็กไม่สามารถระบุประเภทข้อมูลตามระเบียน NDEF รายการแรก ซึ่งจะเกิดขึ้นเมื่อไม่สามารถจับคู่ข้อมูล NDEF กับประเภทหรือ URI ของ MIME หรือเมื่อแท็ก NFC ไม่มีข้อมูล NDEF ตั้งแต่แรก ในกรณีเช่นนี้ ออบเจ็กต์ Tag
ที่มีข้อมูลเกี่ยวกับเทคโนโลยีของแท็กและเพย์โหลดจะรวมอยู่ใน Intent ACTION_TECH_DISCOVERED
แทน
ตารางที่ 1 อธิบายวิธีที่ระบบส่งแท็กแมป TNF และช่องประเภทกับประเภท MIME หรือ URI รวมถึงอธิบาย TNF ใดที่ไม่สามารถแมปกับประเภท MIME หรือ URI
ในกรณีเหล่านี้ ระบบการส่งแท็กจะใช้ ACTION_TECH_DISCOVERED
เช่น หากระบบส่งแท็กพบระเบียนประเภท TNF_ABSOLUTE_URI
ระบบจะแมปช่องประเภทความยาวแปรผันของระเบียนนั้นเป็น URI ระบบการส่งแท็กจะรวม URI นั้นไว้ในช่องข้อมูลของ Intent ACTION_NDEF_DISCOVERED
พร้อมกับข้อมูลอื่นๆ เกี่ยวกับแท็ก เช่น เพย์โหลด ในทางกลับกัน หากตรวจพบระเบียนประเภท TNF_UNKNOWN
ระบบจะสร้าง Intent ที่สรุปเทคโนโลยีของแท็กแทน
รูปแบบชื่อประเภท (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 |
คําจํากัดความของประเภทระเบียน (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 อื่นๆ เมื่อเป็นไปได้ ACTION_TECH_DISCOVERED
: หากไม่มีกิจกรรมลงทะเบียนเพื่อจัดการกับ IntentACTION_NDEF_DISCOVERED
ระบบการส่งแท็กจะพยายามเริ่มแอปพลิเคชันด้วย 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
เนื่องจากเป็นรูปแบบที่เฉพาะเจาะจงที่สุดจากทั้ง 3 รูปแบบ Intent นี้ช่วยให้คุณเริ่มแอปพลิเคชันในเวลาที่เหมาะสมกว่า Intent 2 รายการที่เหลือ ซึ่งจะช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีขึ้น
ขอสิทธิ์เข้าถึง NFC ในไฟล์ Manifest ของ Android
คุณต้องประกาศรายการต่อไปนี้ในไฟล์ AndroidManifest.xml
ก่อนจึงจะเข้าถึงฮาร์ดแวร์ NFC ของอุปกรณ์และจัดการ Intent ของ NFC ได้อย่างถูกต้อง
- องค์ประกอบ 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 รายการใดรายการหนึ่ง 2 รายการ หรือทั้ง 3 รายการในไฟล์ Manifest ของ Android อย่างไรก็ตาม คุณมักจะต้องกรองหา Intent ACTION_NDEF_DISCOVERED
เพื่อให้ควบคุมเวลาเริ่มต้นของแอปพลิเคชันได้มากที่สุด Intent 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
มีไว้เป็นทางเลือกสุดท้ายเท่านั้นสำหรับแอปพลิเคชันที่จะกรองหาในกรณีที่ไม่มีการติดตั้งแอปพลิเคชันอื่นเพื่อจัดการกับ Intent ACTION_NDEF_DISCOVERED
หรือ ACTION_TECH_DISCOVERED
เนื่องจากการติดตั้งใช้งานแท็ก NFC มีความหลากหลายและหลายครั้งอยู่นอกเหนือการควบคุมของคุณ การดำเนินการนี้จึงอาจไม่สามารถทำได้เสมอไป คุณจึงใช้ Intent อื่นๆ 2 รายการเป็นทางเลือกได้เมื่อจำเป็น เมื่อคุณควบคุมประเภทแท็กและข้อมูลที่เขียนได้ เราขอแนะนำให้ใช้ NDEF เพื่อจัดรูปแบบแท็ก ส่วนต่อไปนี้จะอธิบายวิธีกรองตามเจตนาแต่ละประเภท
ACTION_NDEF_DISCOVERED
หากต้องการกรอง Intent ACTION_NDEF_DISCOVERED
ให้ประกาศตัวกรอง Intent พร้อมกับประเภทข้อมูลที่ต้องการกรอง ตัวอย่างตัวกรองต่อไปนี้สําหรับ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
หากกิจกรรมกรอง Intent ACTION_TECH_DISCOVERED
คุณต้องสร้างไฟล์ทรัพยากร XML ที่ระบุเทคโนโลยีที่กิจกรรมรองรับภายในชุด tech-list
ระบบจะถือว่ากิจกรรมของคุณตรงกันหากชุด tech-list
เป็นชุดย่อยของเทคโนโลยีที่แท็กรองรับ ซึ่งคุณจะรับได้โดยการเรียกใช้ getTechList()
เช่น หากแท็กที่สแกนรองรับ MifareCLASS, 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>
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทำงานกับเทคโนโลยีแท็กและ Intent ACTION_TECH_DISCOVERED
ได้ที่การทำงานกับเทคโนโลยีแท็กที่รองรับในเอกสาร NFC ขั้นสูง
ACTION_TAG_DISCOVERED
หากต้องการกรองหา ACTION_TAG_DISCOVERED
ให้ใช้ตัวกรอง Intent ต่อไปนี้
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
รับข้อมูลจาก Intent
หากกิจกรรมเริ่มต้นขึ้นเนื่องจาก Intent ของ NFC คุณดูข้อมูลเกี่ยวกับแท็ก NFC ที่สแกนจาก Intent ได้ Intents อาจมีข้อมูลเพิ่มเติมต่อไปนี้โดยขึ้นอยู่กับแท็กที่สแกน
EXTRA_TAG
(ต้องระบุ): ออบเจ็กต์Tag
ที่แสดงแท็กที่สแกนEXTRA_NDEF_MESSAGES
(ไม่บังคับ): อาร์เรย์ของข้อความ NDEF ที่แยกวิเคราะห์จากแท็ก คุณต้องระบุค่าเพิ่มเติมนี้ในACTION_NDEF_DISCOVERED
IntentEXTRA_ID
(ไม่บังคับ): รหัสระดับล่างของแท็ก
หากต้องการรับข้อมูลเพิ่มเติมเหล่านี้ ให้ตรวจสอบว่ามีการเริ่มกิจกรรมด้วย Intent ของ NFC รายการใดรายการหนึ่งหรือไม่เพื่อให้แน่ใจว่ามีการสแกนแท็ก จากนั้นรับข้อมูลเพิ่มเติมจาก Intent ตัวอย่างต่อไปนี้จะตรวจสอบ Intent ACTION_NDEF_DISCOVERED
และรับข้อความ 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()
จะพร้อมใช้งานเพื่อช่วยคุณสร้าง MIME และระเบียน NDEF ประเภทภายนอก ใช้เมธอดตัวช่วยเหล่านี้ทุกครั้งที่เป็นไปได้เพื่อหลีกเลี่ยงข้อผิดพลาดเมื่อสร้างระเบียน NDEF ด้วยตนเอง
ส่วนนี้อธิบายวิธีสร้างตัวกรองความตั้งใจที่เกี่ยวข้องสำหรับระเบียนด้วย ตัวอย่างระเบียน NDEF ทั้งหมดเหล่านี้ควรอยู่ในระเบียน NDEF แรกของข้อความ NDEF ที่คุณเขียนลงในแท็ก
TNF_ABSOLUTE_URI
หมายเหตุ: เราขอแนะนำให้ใช้ประเภท RTD_URI
แทน TNF_ABSOLUTE_URI
เพราะมีประสิทธิภาพมากกว่า
คุณสร้างระเบียน NDEF ของ TNF_ABSOLUTE_URI
ได้ด้วยวิธีต่อไปนี้
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
คุณสร้างระเบียน NDEF TNF_MIME_MEDIA
ได้ดังนี้
การใช้เมธอด 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
คุณสร้างระเบียน NDEF TNF_WELL_KNOWN
ได้ดังนี้
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
คุณสร้างระเบียน NDEF TNF_WELL_KNOWN
ได้ดังนี้
การใช้เมธอด 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
คุณสร้างระเบียน TNF_EXTERNAL_TYPE
NDEF ได้ดังนี้
การใช้เมธอด 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 และอุปกรณ์ที่ไม่ใช่ Android ได้ดียิ่งขึ้น
หมายเหตุ: URN สำหรับ TNF_EXTERNAL_TYPE
มีรูปแบบมาตรฐานดังนี้
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 (AAR) ซึ่งเปิดตัวใน Android 4.0 (API ระดับ 14) จะช่วยเพิ่มความแน่นอนมากขึ้นว่าแอปพลิเคชันจะเริ่มต้นเมื่อสแกนแท็ก NFC AAR มีชื่อแพ็กเกจของแอปพลิเคชันที่ฝังอยู่ในระเบียน NDEF คุณเพิ่ม AAR ในระเบียน NDEF ใดก็ได้ของข้อความ NDEF เนื่องจาก Android จะค้นหา AAR ทั้งข้อความ NDEF หากพบ AAR ระบบจะเริ่มแอปพลิเคชันตามชื่อแพ็กเกจภายใน AAR หากไม่มีแอปพลิเคชันบนอุปกรณ์ ก็เปิดตัว Google Play เพื่อดาวน์โหลดแอปพลิเคชัน
AAR มีประโยชน์หากคุณไม่ต้องการให้แอปพลิเคชันอื่นๆ กรองสำหรับ Intent เดียวกันและอาจจัดการแท็กเฉพาะที่คุณทำให้ใช้งานได้ ระบบรองรับ AAR ที่ระดับแอปพลิเคชันเท่านั้นเนื่องจากข้อจํากัดของชื่อแพ็กเกจ และจะไม่รองรับที่ระดับกิจกรรมเหมือนกับการกรอง Intent หากต้องการจัดการความตั้งใจที่ระดับกิจกรรม ให้ใช้ตัวกรอง Intent
หากแท็กมี AAR ระบบจะส่งแท็กในลักษณะต่อไปนี้
- ลองเริ่มกิจกรรมโดยใช้ตัวกรอง Intent ตามปกติ หากกิจกรรมที่ตรงกับ Intent ตรงกับ AAR ด้วย ให้เริ่มกิจกรรม
- หากกิจกรรมที่กรอง Intent ไม่ตรงกับ AAR, หากมีกิจกรรมหลายรายการที่จัดการ Intent ได้ หรือหากไม่มีกิจกรรมใดจัดการ Intent ได้ ให้เริ่มแอปพลิเคชันที่ AAR ระบุ
- หากไม่มีแอปพลิเคชันใดเริ่มด้วย AAR ได้ ให้ไปที่ Google Play เพื่อดาวน์โหลดแอปพลิเคชันตาม AAR
หมายเหตุ: คุณลบล้าง AAR และระบบจ่ายงานของ Intent ได้ด้วยระบบการจ่ายงานที่ทำงานอยู่เบื้องหน้า ซึ่งจะช่วยให้กิจกรรมที่ทำงานอยู่เบื้องหน้ามีลำดับความสำคัญสูงสุดเมื่อพบแท็ก 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")} ); )