Dokumen ini menjelaskan topik NFC lanjutan, seperti bekerja dengan berbagai teknologi tag, penulisan ke tag NFC, dan pengiriman latar depan, yang memungkinkan aplikasi di latar depan untuk menangani intent meskipun aplikasi lain memfilter intent yang sama.
Menggunakan teknologi tag yang didukung
Saat menggunakan tag NFC dan perangkat Android, format utama yang Anda gunakan untuk membaca
dan menulis data
pada tag adalah NDEF. Saat perangkat memindai tag dengan data NDEF, Android memberikan dukungan
dalam menguraikan pesan dan mengirimkannya dalam NdefMessage
saat
sebaik mungkin. Namun, ada kasus saat Anda memindai tag yang tidak berisi
Data NDEF atau jika data NDEF tidak dapat dipetakan ke jenis MIME atau URI.
Pada kasus ini, Anda perlu membuka komunikasi langsung dengan tag lalu membaca dan menulis ke tag menggunakan
protokol Anda sendiri (dalam byte mentah). Android menyediakan dukungan umum untuk kasus penggunaan ini dengan
android.nfc.tech
, yang dijelaskan dalam Tabel 1. Anda dapat
menggunakan metode getTechList()
untuk menentukan teknologi
didukung oleh tag dan membuat TagTechnology
yang sesuai
dengan salah satu class yang disediakan oleh android.nfc.tech
Class | Deskripsi |
---|---|
TagTechnology |
Antarmuka yang harus diterapkan oleh semua class teknologi tag. |
NfcA |
Menyediakan akses ke properti NFC-A (ISO 14443-3A) dan operasi I/O. |
NfcB |
Menyediakan akses ke properti NFC-B (ISO 14443-3B) dan operasi I/O. |
NfcF |
Menyediakan akses ke properti NFC-F (JIS 6319-4) dan operasi I/O. |
NfcV |
Menyediakan akses ke properti NFC-V (ISO 15693) dan operasi I/O. |
IsoDep |
Menyediakan akses ke properti ISO-DEP (ISO 14443-4) dan operasi I/O. |
Ndef |
Menyediakan akses ke data dan operasi NDEF pada tag NFC yang telah diformat sebagai NDEF. |
NdefFormatable |
Menyediakan operasi format untuk tag yang dapat diformat NDEF. |
Teknologi tag berikut tidak harus didukung oleh perangkat yang didukung Android.
Class | Deskripsi |
---|---|
MifareClassic |
Memberikan akses ke properti MIFARE Klasik dan operasi I/O, jika perangkat Android ini mendukung MIFARE. |
MifareUltralight |
Memberikan akses ke properti MIFARE Ultralight dan operasi I/O, jika Android ini perangkat ini mendukung MIFARE. |
Menggunakan teknologi tag dan intent ACTION_TECH_DISCOVERED
Saat perangkat memindai tag yang berisi data NDEF, tetapi tidak dapat dipetakan ke MIME atau URI,
sistem pengiriman tag mencoba memulai aktivitas dengan ACTION_TECH_DISCOVERED
intent. ACTION_TECH_DISCOVERED
juga digunakan saat tag
dengan data non-NDEF akan dipindai. Dengan adanya penggantian ini, Anda dapat menggunakan data di tag
secara langsung jika sistem pengiriman tag
tidak bisa menguraikannya untuk Anda. Langkah-langkah dasar
saat bekerja dengan
teknologi tag adalah sebagai berikut:
- Filter intent
ACTION_TECH_DISCOVERED
yang menentukan yang berbeda yang ingin Anda tangani. Lihat Memfilter NFC intent untuk informasi selengkapnya. Secara umum, sistem pengiriman tag mencoba memulai intentACTION_TECH_DISCOVERED
saat pesan NDEF tidak dapat dipetakan ke jenis MIME atau URI, atau jika tag yang dipindai tidak berisi data NDEF. Sebagai mengetahui informasi selengkapnya tentang cara menentukannya, lihat Sistem Pengiriman Tag. - Saat aplikasi Anda menerima intent, dapatkan objek
Tag
dari intent:Kotlin
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- Dapatkan instance
TagTechnology
, dengan memanggil salah satu metodeget
metode factory class dalam paketandroid.nfc.tech
. Anda dapat menghitung teknologi tag yang didukung dengan memanggilgetTechList()
sebelum memanggil metode factoryget
. Misalnya, untuk mendapatkan instanceMifareUltralight
dariTag
, lakukan hal berikut:Kotlin
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
Java
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
Membaca dan menulis ke tag
Membaca dan menulis ke tag NFC melibatkan pemerolehan tag dari intent dan membuka komunikasi dengan tag. Anda harus menentukan stack protokol Anda sendiri untuk membaca dan menulis data pada tag. Namun, perlu diingat bahwa Anda masih dapat membaca dan menulis data NDEF saat bekerja langsung dengan sebuah tag. Anda memiliki kebebasan untuk menyusun objek. Tujuan contoh berikut menunjukkan cara menggunakan tag 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; } }
Menggunakan sistem pengiriman latar depan
Sistem pengiriman latar depan memungkinkan aktivitas mencegat intent dan mengklaim lebih diprioritaskan daripada aktivitas lain yang menangani intent yang sama. Menggunakan sistem ini melibatkan membangun beberapa struktur data agar sistem Android dapat mengirim intent ke aplikasi Anda. Untuk mengaktifkan sistem pengiriman latar depan:
- Tambahkan kode berikut dalam metode
onCreate()
aktivitas Anda:- Membuat objek
PendingIntent
yang dapat diubah sehingga sistem Android dapat mengisinya dengan detail tag saat dipindai.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);
- Deklarasikan filter intent untuk menangani intent yang ingin diintersepsi. Latar depan
sistem pengiriman memeriksa filter intent yang ditetapkan dengan intent yang diterima saat
perangkat memindai tag. Jika sesuai, aplikasi Anda akan menangani intent. Jika ya
tidak cocok, sistem pengiriman latar depan akan kembali ke sistem pengiriman intent.
Menentukan array
null
filter intent dan filter teknologi, menentukan yang ingin Anda filter untuk semua tag yang kembali keTAG_DISCOVERED
intent. Cuplikan kode di bawah ini menangani semua jenis MIME untukNDEF_DISCOVERED
. Anda seharusnya hanya menangani apa yang Anda butuhkan.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, };
- Siapkan array teknologi tag yang ingin ditangani oleh aplikasi Anda. Panggil
Object.class.getName()
untuk mendapatkan class teknologi yang Anda ingin didukung.Kotlin
techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
Java
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
- Membuat objek
- Ganti callback siklus proses aktivitas berikut dan tambahkan logika untuk mengaktifkan dan menonaktifkan
pengiriman latar depan saat aktivitas kalah (
onPause()
) dan mendapatkan kembali fokus (onResume()
).enableForegroundDispatch()
harus dipanggil dari thread utama dan hanya ketika aktivitas berada di latar depan (memanggilonResume()
akan menjamin hal ini). Anda juga perlu menerapkan callbackonNewIntent
untuk memproses data dari NFC yang dipindai .
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 }