Dokumen ini menjelaskan tugas-tugas NFC dasar yang Anda jalankan di Android. Panduan ini menjelaskan cara mengirim dan menerima data NFC dalam bentuk pesan NDEF dan menjelaskan API framework Android yang mendukung fitur-fitur ini. Untuk topik lanjutan lainnya, termasuk diskusi tentang cara menggunakan data non-NDEF, lihat NFC Lanjutan.
Ada dua kasus penggunaan utama saat menggunakan data NDEF dan Android:
- Membaca data NDEF dari tag NFC
- Melakukan beaming pesan NDEF dari satu perangkat ke perangkat lainnya dengan Android BeamTM
Pembacaan data NDEF dari tag NFC ditangani dengan sistem pengiriman tag, yang menganalisis tag NFC yang ditemukan, mengategorikan data dengan tepat, dan memulai aplikasi yang tertarik dengan data yang dikategorikan. Aplikasi yang ingin menangani tag NFC yang dipindai dapat mendeklarasikan filter intent dan meminta untuk menangani data tersebut.
Fitur Android BeamTM memungkinkan perangkat mengirim pesan NDEF ke perangkat lain dengan mengetuk perangkat bersama-sama secara fisik. Interaksi ini memberikan cara yang lebih mudah untuk mengirim data dibandingkan teknologi nirkabel lainnya seperti Bluetooth, karena dengan NFC, penemuan atau penyambungan perangkat secara manual tidak diperlukan. Koneksi otomatis dimulai saat dua perangkat berada dalam jangkauan. Android Beam tersedia melalui serangkaian API NFC, sehingga aplikasi apa pun dapat mengirimkan informasi antar-perangkat. Misalnya, aplikasi Kontak, Browser, dan YouTube menggunakan Android Beam untuk berbagi kontak, halaman web, dan video dengan perangkat lain.
Sistem pengiriman tag
Perangkat Android biasanya mencari tag NFC saat layar tidak terkunci, kecuali NFC dinonaktifkan di menu Setelan perangkat. Saat perangkat Android menemukan tag NFC, perilaku yang diinginkan adalah membuat aktivitas yang paling sesuai menangani intent tanpa menanyakan kepada pengguna aplikasi apa yang akan digunakan. Karena perangkat memindai tag NFC pada rentang yang sangat singkat, ada kemungkinan membuat pengguna memilih aktivitas secara manual akan memaksa mereka untuk menjauhkan perangkat dari tag dan memutus koneksi. Anda harus mengembangkan aktivitas untuk hanya menangani tag NFC yang diperlukan aktivitas Anda untuk mencegah Pemilih Aktivitas muncul.
Untuk membantu Anda mencapai tujuan ini, Android menyediakan sistem pengiriman tag khusus yang menganalisis tag NFC yang dipindai, mengurainya, dan mencoba menemukan aplikasi yang tertarik dengan data yang dipindai. Hal ini dilakukan dengan:
- Mengurai tag NFC dan mencari tahu jenis MIME atau URI yang mengidentifikasi payload data dalam tag.
- Menggabungkan jenis MIME atau URI dan payload dalam satu intent. Dua langkah pertama ini dijelaskan dalam Cara tag NFC dipetakan ke jenis MIME dan URI.
- Memulai aktivitas berdasarkan intent. Hal ini dijelaskan dalam Cara Tag NFC Dikirim ke Aplikasi.
Cara tag NFC dipetakan ke jenis MIME dan URI
Sebelum mulai menulis aplikasi NFC, Anda harus memahami berbagai jenis tag NFC, cara sistem pengiriman tag mengurai tag NFC, dan pekerjaan khusus yang dilakukan sistem pengiriman tag saat mendeteksi pesan NDEF. Tag NFC hadir dalam berbagai teknologi dan juga dapat berisi data yang ditulis dengan berbagai cara. Android memiliki dukungan terbanyak untuk standar NDEF, yang ditentukan oleh Forum NFC.
Data NDEF dienkapsulasi di dalam pesan (NdefMessage
) yang berisi satu
atau beberapa data (NdefRecord
). Setiap data NDEF harus disusun dengan baik sesuai
spesifikasi jenis data yang ingin Anda buat. Android
juga mendukung jenis tag lain yang tidak berisi data NDEF, yang dapat Anda gunakan dengan menggunakan
class dalam paket android.nfc.tech
. Untuk mempelajari teknologi ini lebih lanjut, lihat topik NFC Lanjutan. Penggunaan jenis tag lain ini melibatkan penulisan stack protokol Anda sendiri untuk berkomunikasi dengan tag. Jadi, jika memungkinkan, sebaiknya gunakan NDEF untuk memudahkan pengembangan dan dukungan maksimum bagi perangkat Android.
Catatan: Untuk mendownload spesifikasi lengkap NDEF, buka situs Dokumen Aplikasi & Spesifikasi Forum NFC, lalu lihat Membuat jenis data NDEF umum untuk mengetahui contoh cara membuat data NDEF.
Setelah Anda mengetahui latar belakang tag NFC, bagian berikut menjelaskan secara lebih mendetail cara
Android menangani tag berformat NDEF. Saat memindai tag NFC yang berisi data
berformat NDEF, perangkat Android akan mengurai pesan dan mencoba mencari tahu jenis MIME data atau mengidentifikasi
URI. Untuk melakukannya, sistem akan membaca NdefRecord
pertama dalam NdefMessage
untuk menentukan cara menafsirkan seluruh pesan NDEF (pesan NDEF dapat
memiliki beberapa data NDEF). Dalam pesan NDEF yang diformat dengan baik, NdefRecord
pertama
berisi kolom berikut:
- TNF 3-bit (Format Nama Jenis)
- Menunjukkan cara menafsirkan kolom jenis panjang variabel. Nilai yang valid dijelaskan dalam Tabel 1.
- Jenis panjang variabel
- Menjelaskan jenis data. Jika menggunakan
TNF_WELL_KNOWN
, gunakan kolom ini untuk menentukan Record Type Definition (RTD). Nilai RTD yang valid dijelaskan dalam Tabel 2. - ID panjang variabel
- ID unik untuk data. Kolom ini jarang digunakan, tetapi jika perlu mengidentifikasi tag secara unik, Anda dapat membuat ID untuk tag tersebut.
- Payload panjang variabel
- Payload data sebenarnya yang ingin Anda baca atau tulis. Pesan NDEF dapat berisi beberapa data NDEF, jadi jangan berasumsi bahwa payload lengkap berada dalam data NDEF pertama dari pesan NDEF.
Sistem pengiriman tag menggunakan kolom jenis dan TNF untuk mencoba memetakan jenis MIME atau URI ke pesan NDEF. Jika berhasil, sistem akan mengumpulkan informasi tersebut dalam intent ACTION_NDEF_DISCOVERED
bersama dengan payload sebenarnya. Namun, ada kasus saat sistem pengiriman tag tidak dapat menentukan jenis data berdasarkan data NDEF pertama. Hal ini terjadi jika data NDEF tidak dapat dipetakan ke jenis MIME atau URI, atau saat
tag NFC tidak berisi data NDEF sejak awal. Dalam kasus tersebut, objek Tag
yang memiliki informasi tentang teknologi tag dan payload akan
dienkapsulasi di dalam intent ACTION_TECH_DISCOVERED
.
Tabel 1 menjelaskan cara sistem pengiriman tag memetakan kolom jenis dan
TNF ke jenis MIME atau URI. Tabel ini juga menjelaskan TNF yang tidak dapat dipetakan ke jenis MIME atau URI.
Dalam hal ini, sistem pengiriman tag akan melakukan fallback ke
ACTION_TECH_DISCOVERED
.
Misalnya, jika sistem pengiriman tag menemukan data jenis TNF_ABSOLUTE_URI
, sistem akan memetakan kolom jenis panjang variabel dari data tersebut ke URI. Sistem pengiriman tag mengenkapsulasi URI tersebut dalam kolom data intent ACTION_NDEF_DISCOVERED
bersama dengan informasi lain tentang tag, seperti payload. Di sisi lain, jika menemukan data jenis TNF_UNKNOWN
, parser akan membuat intent yang mengenkapsulasi teknologi tag sebagai gantinya.
Format Nama Jenis (TNF) | Pemetaan |
---|---|
TNF_ABSOLUTE_URI |
URI berdasarkan kolom jenis. |
TNF_EMPTY |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
URI berdasarkan URN dalam kolom jenis. URN dienkode ke dalam kolom jenis NDEF dalam bentuk yang disingkat: <domain_name>:<service_name> .
Android memetakan ini ke URI dalam bentuk:
vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA |
Jenis MIME berdasarkan kolom jenis. |
TNF_UNCHANGED |
Tidak valid dalam data pertama, sehingga melakukan fallback ke
ACTION_TECH_DISCOVERED . |
TNF_UNKNOWN |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
Jenis MIME atau URI bergantung pada Record Type Definition (RTD), yang Anda tetapkan dalam kolom jenis. Lihat Tabel 2 untuk informasi selengkapnya tentang RTD yang tersedia dan pemetaannya. |
Record Type Definition (RTD) | Pemetaan |
---|---|
RTD_ALTERNATIVE_CARRIER |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Melakukan fallback ke ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
URI berdasarkan penguraian payload. |
RTD_TEXT |
Jenis MIME text/plain . |
RTD_URI |
URI berdasarkan payload. |
Cara pengiriman tag NFC ke aplikasi
Saat sistem pengiriman tag selesai membuat intent yang mengenkapsulasi tag NFC dan informasi identitasnya, sistem akan mengirimkan intent ke aplikasi yang berminat yang memfilter intent. Jika ada lebih dari satu aplikasi yang dapat menangani intent, Pemilih Aktivitas akan ditampilkan sehingga pengguna dapat memilih Aktivitas. Sistem pengiriman tag menentukan tiga intent, yang dicantumkan sesuai urutan prioritas tertinggi hingga terendah:
-
ACTION_NDEF_DISCOVERED
: Intent ini digunakan untuk memulai Aktivitas saat tag yang berisi payload NDEF dipindai dan merupakan jenis yang dikenali. Intent ini merupakan intent prioritas tertinggi, dan sistem pengiriman tag akan mencoba memulai Aktivitas dengan intent ini sebelum intent lainnya, jika memungkinkan. ACTION_TECH_DISCOVERED
: Jika tidak ada aktivitas yang terdaftar untuk menangani intentACTION_NDEF_DISCOVERED
, sistem pengiriman tag akan mencoba memulai aplikasi dengan intent ini. Intent ini juga dimulai secara langsung (tanpa memulaiACTION_NDEF_DISCOVERED
terlebih dahulu) jika tag yang dipindai berisi data NDEF yang tidak dapat dipetakan ke jenis MIME atau URI, atau jika tag tidak berisi data NDEF, tetapi merupakan teknologi tag yang dikenal.ACTION_TAG_DISCOVERED
: Intent ini dimulai jika tidak ada aktivitas yang menangani intentACTION_NDEF_DISCOVERED
atauACTION_TECH_DISCOVERED
.
Cara kerja sistem pengiriman tag yang mendasar adalah sebagai berikut:
- Coba memulai Aktivitas dengan intent yang dibuat oleh sistem pengiriman tag
saat mengurai tag NFC (
ACTION_NDEF_DISCOVERED
atauACTION_TECH_DISCOVERED
). - Jika tidak ada aktivitas yang memfilter intent tersebut, cobalah untuk memulai Aktivitas dengan intent prioritas
terendah berikutnya (
ACTION_TECH_DISCOVERED
atauACTION_TAG_DISCOVERED
) hingga aplikasi memfilter intent tersebut atau hingga sistem pengiriman tag mencoba semua intent yang memungkinkan. - Jika tidak ada aplikasi yang memfilter intent apa pun, jangan lakukan apa pun.
Jika memungkinkan, gunakan pesan NDEF dan intent ACTION_NDEF_DISCOVERED
, karena intent ini adalah yang paling spesifik di antara ketiganya. Dengan intent ini, Anda dapat memulai aplikasi pada waktu yang lebih tepat daripada
dua intent lainnya, sehingga memberikan pengalaman yang lebih baik kepada pengguna.
Meminta akses NFC dalam manifes Android
Sebelum Anda dapat mengakses hardware NFC perangkat dan menangani intent NFC dengan benar, deklarasikan
item ini dalam file AndroidManifest.xml
Anda:
- Elemen
<uses-permission>
NFC untuk mengakses hardware NFC:<uses-permission android:name="android.permission.NFC" />
- Versi SDK minimum yang dapat didukung oleh aplikasi Anda. API level 9 hanya mendukung pengiriman tag terbatas melalui
ACTION_TAG_DISCOVERED
, dan hanya memberikan akses ke pesan NDEF melaluiEXTRA_NDEF_MESSAGES
tambahan. Tidak ada properti tag atau operasi I/O lain yang dapat diakses. API level 10 mencakup dukungan pembaca/penulis yang komprehensif serta pengiriman NDEF latar depan, dan API level 14 memberikan cara yang lebih mudah untuk mengirim pesan NDEF ke perangkat lain dengan Android Beam dan metode praktis tambahan untuk membuat data NDEF.<uses-sdk android:minSdkVersion="10"/>
- Elemen
uses-feature
agar aplikasi Anda muncul di Google Play hanya untuk perangkat yang memiliki hardware NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Jika aplikasi Anda menggunakan fungsi NFC, tetapi fungsi tersebut tidak penting bagi aplikasi, Anda dapat menghilangkan elemen
uses-feature
dan memeriksa ketersediaan NFC saat runtime dengan memeriksa apakahgetDefaultAdapter()
adalahnull
.
Memfilter intent NFC
Untuk memulai aplikasi saat tag NFC yang ingin Anda tangani dipindai, aplikasi Anda
dapat memfilter satu, dua, atau ketiga intent NFC dalam manifes Android. Namun, sebaiknya Anda
memfilter intent ACTION_NDEF_DISCOVERED
untuk mengontrol
paling banyak kapan aplikasi Anda dimulai. Intent ACTION_TECH_DISCOVERED
adalah penggantian untuk ACTION_NDEF_DISCOVERED
saat tidak ada aplikasi yang memfilter
ACTION_NDEF_DISCOVERED
atau saat payload bukan
NDEF. Pemfilteran untuk ACTION_TAG_DISCOVERED
biasanya terlalu umum untuk memfilter
kategori. Banyak aplikasi akan memfilter ACTION_NDEF_DISCOVERED
atau ACTION_TECH_DISCOVERED
sebelum ACTION_TAG_DISCOVERED
, sehingga probabilitas aplikasi Anda untuk memulai masih rendah. ACTION_TAG_DISCOVERED
hanya tersedia sebagai upaya terakhir
untuk memfilter aplikasi jika tidak ada aplikasi lain yang diinstal untuk menangani
intent ACTION_NDEF_DISCOVERED
atau ACTION_TECH_DISCOVERED
.
Karena deployment tag NFC bervariasi dan sering kali tidak berada di bawah kendali Anda, hal ini tidak selalu dapat dilakukan. Itulah sebabnya Anda dapat melakukan penggantian ke dua intent lainnya jika diperlukan. Jika memiliki kontrol atas jenis tag dan data yang ditulis, sebaiknya gunakan NDEF untuk memformat tag Anda. Bagian berikut menjelaskan cara memfilter setiap jenis intent.
ACTION_NDEF_DISCOVERED
Untuk memfilter intent ACTION_NDEF_DISCOVERED
, deklarasikan
filter intent bersama dengan jenis data yang ingin Anda filter. Contoh
berikut memfilter intent ACTION_NDEF_DISCOVERED
dengan jenis 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>
Contoh berikut memfilter URI dalam bentuk
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
Jika aktivitas Anda memfilter intent ACTION_TECH_DISCOVERED
,
Anda harus membuat file resource XML yang menentukan teknologi yang didukung aktivitas Anda
dalam kumpulan tech-list
. Aktivitas Anda
dianggap cocok jika kumpulan tech-list
adalah subset teknologi yang
didukung oleh tag, yang dapat Anda peroleh dengan memanggil getTechList()
.
Misalnya, jika tag yang dipindai mendukung MifareClassic, NdefFormatable, dan NfcA, kumpulan
tech-list
Anda harus menentukan ketiga, dua, atau salah satu teknologi tersebut (dan tidak ada
lainnya) agar aktivitas Anda dapat dicocokkan.
Contoh berikut menentukan semua teknologi. Anda harus menghapus kartu yang tidak
didukung oleh tag NFC Anda. Simpan file ini (Anda dapat menamainya sesuai keinginan) dalam folder <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>
Anda juga dapat menentukan beberapa kumpulan tech-list
. Setiap kumpulan tech-list
dianggap secara independen, dan aktivitas Anda dianggap cocok jika satu
kumpulan tech-list
apa pun yang merupakan subset teknologi yang ditampilkan oleh getTechList()
. Kode ini menyediakan semantik AND
dan OR
untuk teknologi yang cocok. Contoh berikut cocok dengan tag yang dapat mendukung
teknologi NfcA dan Ndef atau dapat mendukung teknologi NfcB dan 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>
Dalam file AndroidManifest.xml
, tentukan file resource yang baru saja Anda buat
di elemen <meta-data>
di dalam elemen <activity>
seperti dalam contoh berikut:
<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>
Untuk mengetahui informasi selengkapnya tentang cara menggunakan teknologi tag dan intent ACTION_TECH_DISCOVERED
, lihat Menggunakan Teknologi Tag
yang Didukung dalam dokumen NFC Lanjutan.
ACTION_TAG_DISCOVERED
Untuk memfilter ACTION_TAG_DISCOVERED
, gunakan filter intent
berikut:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Mendapatkan informasi dari intent
Jika aktivitas dimulai karena intent NFC, Anda dapat memperoleh informasi tentang tag NFC yang dipindai dari intent. Intent dapat berisi tambahan berikut bergantung pada tag yang dipindai:
EXTRA_TAG
(wajib): ObjekTag
yang mewakili tag yang dipindai.EXTRA_NDEF_MESSAGES
(opsional): Array pesan NDEF yang diurai dari tag. Tambahan ini bersifat wajib pada intentACTION_NDEF_DISCOVERED
.EXTRA_ID
(opsional): ID tingkat rendah tag.
Untuk mendapatkan tambahan ini, periksa apakah aktivitas Anda diluncurkan dengan salah satu
intent NFC untuk memastikan bahwa tag dipindai, lalu dapatkan tambahan dari
intent tersebut. Contoh berikut memeriksa intent ACTION_NDEF_DISCOVERED
dan mendapatkan pesan NDEF dari intent tambahan.
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. ... } } }
Atau, Anda bisa mendapatkan objek Tag
dari intent, yang akan
berisi payload dan memungkinkan Anda menghitung teknologi tag:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Membuat jenis data NDEF yang umum
Bagian ini menjelaskan cara membuat jenis data NDEF umum untuk membantu Anda saat menulis ke
tag NFC atau mengirim data dengan Android Beam. Mulai Android 4.0 (API level 14), metode createUri()
tersedia untuk membantu Anda membuat
data URI secara otomatis. Mulai dari Android 4.1 (API level 16),
createExternal()
dan createMime()
tersedia untuk membantu Anda membuat
data NDEF jenis eksternal dan MIME. Gunakan metode helper ini jika memungkinkan untuk menghindari kesalahan
saat membuat data NDEF secara manual.
Bagian ini juga menjelaskan cara membuat filter intent yang sesuai untuk data tersebut. Semua contoh data NDEF ini harus berada dalam data NDEF pertama dari pesan NDEF yang Anda tulis ke tag atau beaming.
TNF_ABSOLUTE_URI
Catatan: Sebaiknya gunakan jenis RTD_URI
, bukan TNF_ABSOLUTE_URI
, karena lebih efisien.
Anda dapat membuat data NDEF TNF_ABSOLUTE_URI
dengan cara berikut:
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]);
Filter intent untuk data NDEF sebelumnya akan terlihat seperti ini:
<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
Anda dapat membuat data NDEF TNF_MIME_MEDIA
dengan cara berikut:
Menggunakan metode 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")));
Membuat NdefRecord
secara manual:
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")));
Filter intent untuk data NDEF sebelumnya akan terlihat seperti ini:
<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 dengan RTD_TEXT
Anda dapat membuat data NDEF TNF_WELL_KNOWN
dengan cara berikut:
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; }
Filter intent untuk data NDEF sebelumnya akan terlihat seperti ini:
<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 dengan RTD_URI
Anda dapat membuat data NDEF TNF_WELL_KNOWN
dengan cara berikut:
Menggunakan metode createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Menggunakan metode 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);
Membuat NdefRecord
secara manual:
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);
Filter intent untuk data NDEF sebelumnya akan terlihat seperti ini:
<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
Anda dapat membuat data NDEF TNF_EXTERNAL_TYPE
dengan cara
berikut:
Menggunakan metode 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);
Membuat NdefRecord
secara manual:
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);
Filter intent untuk data NDEF sebelumnya akan terlihat seperti ini:
<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>
Gunakan TNF_EXTERNAL_TYPE
untuk penerapan tag NFC yang lebih umum guna mendukung perangkat yang didukung Android dan non-Android dengan lebih baik.
Catatan: URN untuk TNF_EXTERNAL_TYPE
memiliki format kanonis:
urn:nfc:ext:example.com:externalType
, tetapi spesifikasi RTD Forum NFC
mendeklarasikan bahwa bagian urn:nfc:ext:
dari URN harus dihilangkan dari
data NDEF. Jadi, Anda hanya perlu menyediakan domain (example.com
dalam contoh)
dan jenis (externalType
dalam contoh) yang dipisahkan dengan tanda titik dua.
Saat mengirim TNF_EXTERNAL_TYPE
, Android akan mengonversi URN urn:nfc:ext:example.com:externalType
menjadi URI vnd.android.nfc://ext/example.com:externalType
, yang dideklarasikan
filter intent dalam contoh.
Data aplikasi Android
Diperkenalkan di Android 4.0 (API level 14), Data Aplikasi Android (AAR) memberikan kepastian yang lebih kuat bahwa aplikasi Anda dimulai saat tag NFC dipindai. AAR memiliki nama paket aplikasi yang disematkan di dalam data NDEF. Anda dapat menambahkan AAR ke data NDEF apa pun dari pesan NDEF, karena Android akan menelusuri AAR dalam seluruh pesan NDEF. Jika menemukan AAR, aplikasi akan dimulai berdasarkan nama paket dalam AAR. Jika aplikasi tidak ada di perangkat, Google Play akan diluncurkan untuk mendownload aplikasi.
AAR berguna jika Anda ingin mencegah aplikasi lain memfilter intent yang sama dan berpotensi menangani tag tertentu yang telah di-deploy. AAR hanya didukung di level aplikasi karena batasan nama paket, dan bukan di tingkat Aktivitas seperti pemfilteran intent. Jika Anda ingin menangani intent di tingkat Aktivitas, gunakan filter intent.
Jika tag berisi AAR, sistem pengiriman tag akan melakukan pengiriman dengan cara berikut:
- Cobalah memulai Aktivitas menggunakan filter intent seperti biasa. Jika Aktivitas yang cocok dengan intent juga cocok dengan AAR, mulai Aktivitas.
- Jika Aktivitas yang memfilter intent tidak cocok dengan AAR, jika beberapa Aktivitas dapat menangani intent, atau jika tidak ada Aktivitas yang menangani intent, mulailah aplikasi yang ditentukan oleh AAR.
- Jika tidak ada aplikasi yang dapat memulai dengan AAR, buka Google Play untuk mendownload aplikasi berdasarkan AAR.
Catatan: Anda dapat mengganti AAR dan sistem pengiriman intent dengan sistem pengiriman latar depan, yang memungkinkan aktivitas latar depan diprioritaskan saat tag NFC ditemukan. Dengan metode ini, aktivitas harus berada di latar depan untuk mengganti AAR dan sistem pengiriman intent.
Jika masih ingin memfilter tag yang dipindai yang tidak berisi AAR, Anda dapat mendeklarasikan filter intent seperti biasa. Hal ini berguna jika aplikasi Anda tertarik dengan tag lain yang tidak berisi AAR. Misalnya, mungkin Anda ingin menjamin bahwa aplikasi Anda menangani tag kepemilikan yang di-deploy serta tag umum yang di-deploy oleh pihak ketiga. Perlu diingat bahwa AAR ditujukan khusus untuk perangkat Android 4.0 atau yang lebih baru. Jadi, saat men-deploy tag, kemungkinan besar Anda perlu menggunakan kombinasi jenis AAR dan MIME/URI untuk mendukung berbagai perangkat. Selain itu, saat menerapkan tag NFC, pikirkan cara Anda dalam menulis tag NFC untuk mengaktifkan dukungan bagi sebagian besar perangkat (perangkat Android dan perangkat lainnya). Anda dapat melakukannya dengan menentukan jenis MIME atau URI yang relatif unik untuk memudahkan aplikasi membedakannya.
Android menyediakan API sederhana untuk membuat AAR,
createApplicationRecord()
. Anda hanya perlu
menyematkan AAR di mana saja dalam NdefMessage
. Anda tidak perlu
menggunakan data pertama NdefMessage
, kecuali jika AAR adalah satu-satunya
data dalam NdefMessage
. Hal ini karena sistem Android
memeriksa data pertama NdefMessage
untuk menentukan jenis MIME atau
URI tag, yang digunakan untuk membuat intent yang dapat difilter oleh aplikasi. Kode berikut
menunjukkan cara membuat 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")} ); )
Melakukan beaming pesan NDEF ke perangkat lain
Android Beam memungkinkan pertukaran data peer-to-peer yang sederhana antara dua perangkat Android. Aplikasi yang ingin melakukan beam data ke perangkat lain harus berada di latar depan dan perangkat yang menerima data tidak boleh terkunci. Saat perangkat beaming melakukan kontak yang cukup dekat dengan perangkat penerima, perangkat beaming akan menampilkan UI "Sentuh untuk melakukan beam". Kemudian, pengguna dapat memilih apakah akan melakukan beaming pesan ke perangkat penerima atau tidak.
Catatan: Pengiriman NDEF latar depan tersedia di API level 10,
yang menyediakan fungsi serupa dengan Android Beam. API ini sudah tidak digunakan lagi, tetapi
tersedia untuk mendukung perangkat lama. Lihat enableForegroundNdefPush()
untuk mengetahui informasi selengkapnya.
Anda dapat mengaktifkan Android Beam untuk aplikasi dengan memanggil salah satu dari dua metode berikut:
setNdefPushMessage()
: MenerimaNdefMessage
untuk ditetapkan sebagai pesan yang akan di-beam. Otomatis melakukan beaming pesan saat dua perangkat berada dalam jarak yang cukup dekat.setNdefPushMessageCallback()
: Menerima callback yang berisicreateNdefMessage()
yang dipanggil saat perangkat berada dalam jangkauan untuk melakukan beaming data. Callback memungkinkan Anda membuat pesan NDEF hanya jika diperlukan.
Suatu aktivitas hanya dapat mengirim satu pesan NDEF dalam satu waktu, sehingga setNdefPushMessageCallback()
lebih diprioritaskan
daripada setNdefPushMessage()
jika keduanya ditetapkan. Untuk menggunakan
Android Beam, panduan umum berikut harus dipenuhi:
- Aktivitas yang melakukan beaming data harus berada di latar depan. Layar kedua perangkat harus tidak terkunci.
- Anda harus mengenkapsulasi data yang akan di-beam dalam objek
NdefMessage
. - Perangkat NFC yang menerima data yang di-beam harus mendukung
protokol push NDEF
com.android.npp
atau SNEP (Simple NDEF Exchange Protocol) Forum NFC. Protokolcom.android.npp
diperlukan untuk perangkat di API level 9 (Android 2.3) hingga API level 13 (Android 3.2).com.android.npp
dan SNEP diperlukan di API level 14 (Android 4.0) dan yang lebih baru.
Catatan: Jika aktivitas Anda mengaktifkan Android Beam dan berada di latar depan, sistem pengiriman intent standar akan dinonaktifkan. Namun, jika aktivitas Anda juga mengaktifkan pengiriman latar depan, aktivitas tersebut masih dapat memindai tag yang cocok dengan filter intent yang ditetapkan dalam pengiriman latar depan.
Untuk mengaktifkan Android Beam:
- Buat
NdefMessage
yang berisiNdefRecord
yang ingin Anda kirim ke perangkat lain. - Panggil
setNdefPushMessage()
denganNdefMessage
atau panggilsetNdefPushMessageCallback
yang meneruskan objekNfcAdapter.CreateNdefMessageCallback
dalam metodeonCreate()
aktivitas Anda. Metode ini memerlukan setidaknya satu aktivitas yang ingin Anda aktifkan dengan Android Beam, beserta daftar opsional aktivitas lain untuk diaktifkan.Secara umum, biasanya Anda menggunakan
setNdefPushMessage()
jika Aktivitas hanya perlu mendorong pesan NDEF yang sama setiap saat, saat dua perangkat berada dalam jangkauan untuk berkomunikasi. Anda menggunakansetNdefPushMessageCallback
saat aplikasi memperhatikan konteks aplikasi saat ini dan ingin mengirim pesan NDEF, bergantung pada apa yang dilakukan pengguna di aplikasi Anda.
Contoh berikut menunjukkan cara aktivitas sederhana memanggil NfcAdapter.CreateNdefMessageCallback
dalam metode onCreate()
suatu
aktivitas (lihat AndroidBeamDemo
untuk contoh lengkapnya). Contoh ini juga memiliki metode untuk membantu Anda membuat data MIME:
Kotlin
package com.example.android.beam import android.app.Activity import android.content.Intent import android.nfc.NdefMessage import android.nfc.NdefRecord import android.nfc.NfcAdapter import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.NfcEvent import android.os.Bundle import android.os.Parcelable import android.widget.TextView import android.widget.Toast import java.nio.charset.Charset class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback { private var nfcAdapter: NfcAdapter? = null private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) textView = findViewById(R.id.textView) // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show() finish() return } // Register callback nfcAdapter?.setNdefPushMessageCallback(this, this) } override fun createNdefMessage(event: NfcEvent): NdefMessage { val text = "Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis() return NdefMessage( arrayOf( createMime("application/vnd.com.example.android.beam", text.toByteArray()) ) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. *///,NdefRecord.createApplicationRecord("com.example.android.beam") ) } override fun onResume() { super.onResume() // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { processIntent(intent) } } override fun onNewIntent(intent: Intent) { // onResume gets called after this to handle the intent setIntent(intent) } /** * Parses the NDEF Message from the intent and prints to the TextView */ private fun processIntent(intent: Intent) { textView = findViewById(R.id.textView) // only one message sent during the beam intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs -> (rawMsgs[0] as NdefMessage).apply { // record 0 contains the MIME type, record 1 is the AAR, if present textView.text = String(records[0].payload) } } } }
Java
package com.example.android.beam; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; public class Beam extends Activity implements CreateNdefMessageCallback { NfcAdapter nfcAdapter; TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); finish(); return; } // Register callback nfcAdapter.setNdefPushMessageCallback(this, this); } @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = ("Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis()); NdefMessage msg = new NdefMessage( new NdefRecord[] { createMime( "application/vnd.com.example.android.beam", text.getBytes()) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") }); return msg; } @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { textView = (TextView) findViewById(R.id.textView); Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present textView.setText(new String(msg.getRecords()[0].getPayload())); } }
Perhatikan bahwa kode ini berisi komentar AAR yang dapat dihapus. Jika Anda mengaktifkan AAR, aplikasi yang ditentukan dalam AAR akan selalu menerima pesan Android Beam. Jika aplikasi tidak ada, Google Play akan mulai mendownload aplikasi. Oleh karena itu, filter intent berikut secara teknis tidak diperlukan untuk perangkat Android 4.0 atau yang lebih baru jika AAR digunakan:
<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>
Dengan filter intent ini, aplikasi com.example.android.beam
kini dapat dimulai
saat memindai tag NFC atau menerima Android Beam dengan AAR jenis
com.example.android.beam
, atau saat pesan berformat NDEF berisi data MIME
jenis application/vnd.com.example.android.beam
.
Meskipun AAR menjamin aplikasi akan dimulai atau didownload, filter intent direkomendasikan karena memungkinkan Anda memulai Aktivitas pilihan dalam aplikasi, bukan selalu memulai Aktivitas utama dalam paket yang ditentukan oleh AAR. AAR tidak memiliki perincian tingkat Aktivitas. Selain itu, karena beberapa perangkat Android tidak mendukung AAR, sebaiknya Anda juga menyematkan informasi identitas dalam data NDEF pertama dari pesan NDEF dan memfilternya juga untuk berjaga-jaga. Lihat Membuat Jenis Data NDEF Umum untuk mengetahui informasi selengkapnya tentang cara membuat data.