เอกสารนี้อธิบายถึงหัวข้อ NFC ขั้นสูง เช่น การทำงานกับเทคโนโลยีแท็กต่างๆ การเขียนไปยังแท็ก NFC และการจ่ายงานในเบื้องหน้า ซึ่งช่วยให้แอปพลิเคชันในเบื้องหน้าสามารถ จัดการ Intent แม้ว่าแอปพลิเคชันอื่นๆ จะกรองรายการเดียวกันก็ตาม
ทำงานกับเทคโนโลยีแท็กที่รองรับ
เมื่อทำงานกับแท็ก NFC และอุปกรณ์ที่ใช้ Android รูปแบบหลักที่คุณใช้อ่าน
และเขียนข้อมูลบนแท็กคือ NDEF Android จะให้การสนับสนุนเมื่ออุปกรณ์สแกนแท็กที่มีข้อมูล NDEF
ในการแยกวิเคราะห์ข้อความและนำส่งใน NdefMessage
เมื่อ
เท่าที่จะเป็นไปได้ อย่างไรก็ตาม มีบางกรณีเมื่อคุณสแกนแท็กที่ไม่มี
ข้อมูล NDEF หรือเมื่อข้อมูล NDEF จับคู่กับประเภท MIME หรือ URI ไม่ได้
ในกรณีเหล่านี้ คุณต้องเปิดการสื่อสารโดยตรงกับแท็ก แล้วอ่านและเขียนลงในแท็กด้วย
โปรโตคอลของคุณเอง (ในไบต์ดิบ) Android ให้การสนับสนุนทั่วไปสำหรับ Use Case เหล่านี้ด้วย
android.nfc.tech
ซึ่งอธิบายไว้ในตาราง 1 คุณสามารถ
ใช้เมธอด getTechList()
เพื่อระบุเทคโนโลยี
แท็กรองรับและสร้าง TagTechnology
ที่เกี่ยวข้อง
ออบเจ็กต์ที่มีคลาสใดคลาสหนึ่งจัดเตรียมโดย android.nfc.tech
ชั้น | คำอธิบาย |
---|---|
TagTechnology |
อินเทอร์เฟซที่คลาสเทคโนโลยีแท็กทั้งหมดต้องติดตั้งใช้งาน |
NfcA |
ให้สิทธิ์เข้าถึงคุณสมบัติ NFC-A (ISO 14443-3A) และการดำเนินการ I/O |
NfcB |
ให้สิทธิ์เข้าถึงคุณสมบัติ NFC-B (ISO 14443-3B) และการดำเนินการ I/O |
NfcF |
ให้สิทธิ์เข้าถึงพร็อพเพอร์ตี้ NFC-F (JIS 6319-4) และการดำเนินการ I/O |
NfcV |
ให้สิทธิ์เข้าถึงคุณสมบัติ NFC-V (ISO 15693) และการดำเนินการ I/O |
IsoDep |
ให้สิทธิ์เข้าถึงคุณสมบัติ ISO-DEP (ISO 14443-4) และการดำเนินการ I/O |
Ndef |
ให้สิทธิ์เข้าถึงข้อมูลและการดำเนินการ NDEF ในแท็ก NFC ที่มีการจัดรูปแบบเป็น NDEF |
NdefFormatable |
ระบุการดำเนินการของรูปแบบสำหรับแท็กที่อาจอยู่ในรูปแบบ NDEF ได้ |
อุปกรณ์ที่ใช้ Android ไม่จำเป็นต้องใช้เทคโนโลยีแท็กต่อไปนี้
ชั้น | คำอธิบาย |
---|---|
MifareClassic |
ให้สิทธิ์เข้าถึงพร็อพเพอร์ตี้ MIFARE Classic และการดำเนินการ I/O หากอุปกรณ์ Android นี้ รองรับ MIFARE |
MifareUltralight |
ให้สิทธิ์เข้าถึงพร็อพเพอร์ตี้ MIFARE Ultralight และการดําเนินการ I/O หาก Android เครื่องนี้ อุปกรณ์รองรับ MIFARE |
ทำงานกับเทคโนโลยีแท็กและความตั้งใจ ACTION_TECH_DISCOVERED
เมื่ออุปกรณ์สแกนแท็กที่มีข้อมูล NDEF แต่ไม่ได้แมปกับ MIME หรือ URI
ระบบจ่ายแท็กพยายามเริ่มกิจกรรมด้วย ACTION_TECH_DISCOVERED
Intent ระบบจะใช้ ACTION_TECH_DISCOVERED
ด้วยเช่นกันเมื่อแท็ก
ระบบจะสแกนข้อมูลที่ไม่ใช่ NDEF การมีทางเลือกสำรองนี้ช่วยให้คุณทำงานกับข้อมูลในแท็กได้
โดยตรง หากระบบจ่ายแท็กไม่สามารถแยกวิเคราะห์ให้คุณ ขั้นตอนพื้นฐานในการทำงานกับ
เทคโนโลยีแท็กมีดังนี้
- ตัวกรองสำหรับ Intent
ACTION_TECH_DISCOVERED
ที่ระบุ เทคโนโลยีแท็กที่คุณต้องการจัดการ โปรดดูการกรองสำหรับ NFC Intent เพื่อดูข้อมูลเพิ่มเติม โดยทั่วไป ระบบการจ่ายแท็กจะพยายามเริ่มต้น IntentACTION_TECH_DISCOVERED
เมื่อมีข้อความ NDEF จะแมปกับประเภท MIME หรือ URI ไม่ได้ หรือหากแท็กที่สแกนไม่มีข้อมูล NDEF สำหรับ ข้อมูลเพิ่มเติมเกี่ยวกับวิธีกำหนด โปรดดูระบบการจ่ายแท็ก - เมื่อแอปพลิเคชันได้รับ Intent ให้รับออบเจ็กต์
Tag
จาก จุดประสงค์:Kotlin
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- รับอินสแตนซ์ของ
TagTechnology
โดยการเรียกใช้หนึ่งใน มีเมธอดจากโรงงานget
รายการของคลาสในแพ็กเกจandroid.nfc.tech
คุณสามารถ แจกแจงเทคโนโลยีที่รองรับของแท็กโดยการเรียกใช้getTechList()
ก่อนเรียกใช้เมธอดget
จากโรงงาน เช่น หากต้องการรับอินสแตนซ์ ของMifareUltralight
จากTag
ให้ทำดังนี้Kotlin
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
Java
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
อ่านและเขียนไปยังแท็ก
การอ่านและการเขียนไปยังแท็ก NFC เกี่ยวข้องกับการรับแท็กจาก Intent และ การเปิดการสื่อสารด้วยแท็ก คุณต้องระบุสแต็กโปรโตคอลของคุณเองเพื่ออ่านและเขียนข้อมูล ลงในแท็ก อย่างไรก็ตาม โปรดทราบว่าคุณยังคงอ่านและเขียนข้อมูล NDEF ได้เมื่อทำงาน โดยตรงด้วยแท็ก ขึ้นอยู่กับคุณว่าต้องการจัดโครงสร้างของสิ่งต่างๆ อย่างไร ตัวอย่างต่อไปนี้แสดงวิธีทำงานกับแท็ก MIFARE Ultralight
Kotlin
package com.example.android.nfc import android.nfc.Tag import android.nfc.tech.MifareUltralight import java.io.IOException import java.nio.charset.Charset class MifareUltralightTagTester { fun writeTag(tag: Tag, tagText: String) { MifareUltralight.get(tag)?.use { ultralight -> ultralight.connect() Charset.forName("US-ASCII").also { usAscii -> ultralight.writePage(4, "abcd".toByteArray(usAscii)) ultralight.writePage(5, "efgh".toByteArray(usAscii)) ultralight.writePage(6, "ijkl".toByteArray(usAscii)) ultralight.writePage(7, "mnop".toByteArray(usAscii)) } } } fun readTag(tag: Tag): String? { return MifareUltralight.get(tag)?.use { mifare -> mifare.connect() val payload = mifare.readPages(4) String(payload, Charset.forName("US-ASCII")) } } }
Java
package com.example.android.nfc; import android.nfc.Tag; import android.nfc.tech.MifareUltralight; import android.util.Log; import java.io.IOException; import java.nio.charset.Charset; public class MifareUltralightTagTester { private static final String TAG = MifareUltralightTagTester.class.getSimpleName(); public void writeTag(Tag tag, String tagText) { MifareUltralight ultralight = MifareUltralight.get(tag); try { ultralight.connect(); ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII"))); } catch (IOException e) { Log.e(TAG, "IOException while writing MifareUltralight...", e); } finally { try { ultralight.close(); } catch (IOException e) { Log.e(TAG, "IOException while closing MifareUltralight...", e); } } } public String readTag(Tag tag) { MifareUltralight mifare = MifareUltralight.get(tag); try { mifare.connect(); byte[] payload = mifare.readPages(4); return new String(payload, Charset.forName("US-ASCII")); } catch (IOException e) { Log.e(TAG, "IOException while reading MifareUltralight message...", e); } finally { if (mifare != null) { try { mifare.close(); } catch (IOException e) { Log.e(TAG, "Error closing tag...", e); } } } return null; } }
ใช้ระบบการจ่ายงานที่ทำงานอยู่เบื้องหน้า
ระบบการจ่ายงานที่ทำงานอยู่เบื้องหน้าอนุญาตให้กิจกรรมสกัดกั้นความตั้งใจและการอ้างสิทธิ์ได้ ลำดับความสำคัญเหนือกิจกรรมอื่นๆ ที่จัดการความตั้งใจเดียวกัน การใช้ระบบนี้เกี่ยวข้องกับ สร้างโครงสร้างข้อมูลสองสามแบบเพื่อให้ระบบ Android สามารถส่ง กับแอปพลิเคชันของคุณ วิธีเปิดใช้ระบบการจ่ายงานที่ทำงานอยู่เบื้องหน้า
- เพิ่มโค้ดต่อไปนี้ในเมธอด
onCreate()
ของกิจกรรม- สร้างออบเจ็กต์
PendingIntent
ที่เปลี่ยนแปลงได้เพื่อให้ระบบ Android ป้อนข้อมูลได้ พร้อมรายละเอียดของแท็กเมื่อสแกนKotlin
val intent = Intent(this, javaClass).apply { addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) } var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE)
Java
PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE);
- ประกาศตัวกรอง Intent เพื่อจัดการ Intent ที่คุณต้องการสกัดกั้น เบื้องหน้า
ระบบการจ่ายงานจะตรวจสอบตัวกรอง Intent ที่ระบุกับ Intent ที่ได้รับเมื่อ
อุปกรณ์จะสแกนแท็ก หากตรงกัน แอปพลิเคชันของคุณจะจัดการ Intent หากใช่
ไม่ตรงกัน ระบบการจ่ายงานที่ทำงานอยู่เบื้องหน้าจะกลับไปใช้ระบบการจ่ายงาน Intent แทน
การระบุอาร์เรย์
null
ของตัวกรอง Intent และตัวกรองเทคโนโลยีจะระบุ ที่คุณต้องการกรองสำหรับแท็กทั้งหมดที่สำรองเป็นTAG_DISCOVERED
Intent ข้อมูลโค้ดด้านล่างจะรองรับ MIME ทุกประเภทสำหรับNDEF_DISCOVERED
คุณ ควรจะจัดการเฉพาะ ส่วนที่คุณต้องการเท่านั้นKotlin
val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply { try { addDataType("*/*") /* Handles all MIME based dispatches. You should specify only the ones that you need. */ } catch (e: IntentFilter.MalformedMimeTypeException) { throw RuntimeException("fail", e) } } intentFiltersArray = arrayOf(ndef)
Java
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*"); /* Handles all MIME based dispatches. You should specify only the ones that you need. */ } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } intentFiltersArray = new IntentFilter[] {ndef, };
- ตั้งค่าอาร์เรย์ของเทคโนโลยีแท็กที่แอปพลิเคชันของคุณต้องการจัดการ เรียกใช้
Object.class.getName()
วิธีการรับข้อมูลคลาสของเทคโนโลยี ต้องการสนับสนุนKotlin
techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
Java
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
- สร้างออบเจ็กต์
- ลบล้าง Callback ของวงจรกิจกรรมต่อไปนี้ และเพิ่มตรรกะเพื่อเปิดใช้และปิดใช้
การจ่ายงานเบื้องหน้าเมื่อกิจกรรมหายไป (
onPause()
) และจะโฟกัสได้อีกครั้ง (onResume()
) ต้องเรียกenableForegroundDispatch()
จาก เทรดหลักและเฉพาะเมื่อกิจกรรมอยู่เบื้องหน้า (การเรียกใช้ในonResume()
รับประกันการดำเนินการนี้) คุณต้องใช้ CallbackonNewIntent
ในการประมวลผลข้อมูลจาก NFC ที่สแกนด้วย แท็ก
Kotlin
public override fun onPause() { super.onPause() adapter.disableForegroundDispatch(this) } public override fun onResume() { super.onResume() adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray) } public override fun onNewIntent(intent: Intent) { val tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) // do something with tagFromIntent }
Java
public void onPause() { super.onPause(); adapter.disableForegroundDispatch(this); } public void onResume() { super.onResume(); adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray); } public void onNewIntent(Intent intent) { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // do something with tagFromIntent }