این سند مباحث پیشرفته NFC را توصیف می کند ، مانند کار با فن آوری های مختلف برچسب ، نوشتن به برچسب های NFC و اعزام پیش زمینه ، که به یک برنامه در پیش زمینه اجازه می دهد تا حتی در مواردی که سایر برنامه ها برای همان موارد فیلتر می شوند ، اهداف را کنترل کنند.
با فناوری های برچسب پشتیبانی شده کار کنید
هنگام کار با برچسب های NFC و دستگاه های اندرویدی ، قالب اصلی که برای خواندن و نوشتن داده ها در برچسب ها استفاده می کنید NDEF است. هنگامی که یک دستگاه برچسب را با داده های NDEF اسکن می کند ، Android در تجزیه و تحلیل پیام پشتیبانی می کند و در صورت امکان آن را در NdefMessage
تحویل می دهد. مواردی وجود دارد ، با این حال ، هنگامی که برچسب را اسکن می کنید که حاوی داده های NDEF نیست یا وقتی داده های NDEF نمی توانند به یک نوع MIME یا URI نقشه برداری شوند. در این موارد ، شما باید ارتباطات را مستقیماً با برچسب باز کنید و با پروتکل خود (در بایت های خام) برای آن بخوانید و بنویسید. Android با بسته android.nfc.tech
، که در جدول 1 شرح داده شده است ، پشتیبانی عمومی را برای این موارد استفاده ارائه می دهد. برای تعیین فن آوری های پشتیبانی شده توسط TAG می توانید از روش getTechList()
استفاده کنید و با یکی از کلاسهای ارائه شده توسط android.nfc.tech
شیء مربوط به TagTechnology
را ایجاد کنید
کلاس | توضیحات |
---|---|
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 | Provides access to NFC-V (ISO 15693) properties and I/O operations. |
IsoDep | Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations. |
Ndef | Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF. |
NdefFormatable | Provides a format operations for tags that may be NDEF formattable. |
The following tag technologies are not required to be supported by Android-powered devices.
کلاس | توضیحات |
---|---|
MifareClassic | Provides access to MIFARE Classic properties and I/O operations, if this Android device supports MIFARE. |
MifareUltralight | Provides access to MIFARE Ultralight properties and I/O operations, if this Android device supports MIFARE. |
Work with tag technologies and the ACTION_TECH_DISCOVERED intent
هنگامی که یک دستگاه برچسب ای را که داده های NDEF را در آن قرار داده است ، اسکن می کند ، اما نمی توان آن را به یک MIME یا URI نقشه برداری کرد ، سیستم Dispatch Tag سعی می کند با هدف ACTION_TECH_DISCOVERED
فعالیتی را آغاز کند. The ACTION_TECH_DISCOVERED
is also used when a tag with non-NDEF data is scanned. Having this fallback allows you to work with the data on the tag directly if the tag dispatch system could not parse it for you. The basic steps when working with tag technologies are as follows:
- Filter for an
ACTION_TECH_DISCOVERED
intent specifying the tag technologies that you want to handle. See Filtering for NFC intents for more information. به طور کلی ، سیستم Dispatch TAG سعی می کند یک هدفACTION_TECH_DISCOVERED
را شروع کند که یک پیام NDEF نتواند به یک نوع MIME یا URI نقشه برداری شود ، یا اگر برچسب اسکن شده حاوی داده NDEF نبود. For more information on how this is determined, see The Tag Dispatch System . - When your application receives the intent, obtain the
Tag
object from the intent: - Obtain an instance of a
TagTechnology
, by calling one of theget
factory methods of the classes in theandroid.nfc.tech
package. You can enumerate the supported technologies of the tag by callinggetTechList()
before calling aget
factory method. For example, to obtain an instance ofMifareUltralight
from aTag
, do the following:
خواندن و نوشتن در برچسب ها
Reading and writing to an NFC tag involves obtaining the tag from the intent and opening communication with the tag. You must define your own protocol stack to read and write data to the tag. Keep in mind, however, that you can still read and write NDEF data when working directly with a tag. It is up to you how you want to structure things. The following example shows how to work with a MIFARE Ultralight tag.
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"))
}
}
}
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;
}
}
از سیستم اعزام پیش زمینه استفاده کنید
The foreground dispatch system allows an activity to intercept an intent and claim priority over other activities that handle the same intent. استفاده از این سیستم شامل ساخت چند ساختار داده برای سیستم Android است تا بتواند اهداف مناسب را برای برنامه شما ارسال کند. برای فعال کردن سیستم اعزام پیش زمینه:
- Add the following code in the
onCreate()
method of your activity:- Create a mutable
PendingIntent
object so the Android system can populate it with the details of the tag when it is scanned.val intent = Intent(this, javaClass).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_MUTABLE)PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
PendingIntent.FLAG_MUTABLE); - Declare intent filters to handle the intents that you want to intercept. The foreground dispatch system checks the specified intent filters with the intent that is received when the device scans a tag. If it matches, then your application handles the intent. If it does not match, the foreground dispatch system falls back to the intent dispatch system. با مشخص کردن یک آرایه
null
از فیلترهای قصد و فیلترهای فناوری ، مشخص می کند که می خواهید برای همه برچسب هایی که به هدفTAG_DISCOVERED
بازگردند ، فیلتر کنید. The code snippet below handles all MIME types forNDEF_DISCOVERED
. شما فقط باید آنهایی را که نیاز دارید مدیریت کنید.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)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()
تماس بگیرید.
- Create a mutable
- در هنگام از دست دادن فعالیت (
onPause()
) و تمرکز مجدد (onResume()
) ، به تماس های چرخه چرخه فعالیت زیر و منطقی اضافه کنید تا بتوانید اعزام پیش زمینه را فعال و غیرفعال کنید.enableForegroundDispatch()
باید از موضوع اصلی فراخوانی کرد و فقط وقتی فعالیت در پیش زمینه باشد (فراخوانی درonResume()
این را تضمین می کند). You also need to implement theonNewIntent
callback to process the data from the scanned NFC tag.
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
}
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
}