این سند موضوعات پیشرفته NFC را شرح میدهد، مانند کار با فناوریهای مختلف برچسب، نوشتن روی برچسبهای NFC، و ارسال پیشزمینه، که به یک برنامه در پیشزمینه اجازه میدهد تا اهداف را مدیریت کند، حتی زمانی که برنامههای دیگر برای همان اهداف فیلتر میکنند.
کار با فناوریهای برچسب پشتیبانیشده
هنگام کار با برچسبهای NFC و دستگاههای مجهز به Android، قالب اصلی که برای خواندن و نوشتن دادهها روی برچسبها استفاده میکنید NDEF است. وقتی دستگاهی برچسبی را با دادههای NDEF اسکن میکند، Android از تجزیه پیام و ارائه آن در NdefMessage درصورت امکان پشتیبانی میکند. بااینحال، مواردی وجود دارد که برچسبی را اسکن میکنید که حاوی دادههای NDEF نیست یا دادههای NDEF نمیتوانند به نوع MIME یا URI نگاشت شوند.
در این موارد، باید ارتباط را مستقیماً با برچسب باز کنید و با پروتکل خودتان (در بایتهای خام) در آن بخوانید و بنویسید. Android با بسته android.nfc.tech که در جدول ۱ شرح داده شده است، پشتیبانی عمومی برای این موارد استفاده ارائه میدهد. میتوانید
از روش getTechList() برای تعیین فناوریهای
پشتیبانیشده توسط برچسب استفاده کنید و شیء TagTechnology مربوطه را
با یکی از کلاسهای ارائهشده توسط android.nfc.tech ایجاد کنید
جدول ۱. فناوریهای برچسب پشتیبانیشده
| کلاس | شرح |
|---|---|
TagTechnology |
میانایی که همه کلاسهای فناوری برچسب باید پیادهسازی کنند. |
NfcA |
دسترسی به ویژگیهای NFC-A (ISO 14443-3A) و عملیات ورودی/خروجی را فراهم میکند. |
NfcB |
دسترسی به ویژگیهای NFC-B (ISO 14443-3B) و عملیات ورودی/خروجی را فراهم میکند. |
NfcF |
دسترسی به ویژگیهای NFC-F (JIS 6319-4) و عملیات ورودی/خروجی را فراهم میکند. |
NfcV |
دسترسی به ویژگیهای NFC-V (ISO 15693) و عملیات ورودی/خروجی را فراهم میکند. |
IsoDep |
دسترسی به ویژگیهای ISO-DEP (ISO 14443-4) و عملیات ورودی/خروجی را فراهم میکند. |
Ndef |
دسترسی به دادههای NDEF و عملیات روی برچسبهای NFC را که بهعنوان NDEF قالببندی شدهاند فراهم میکند. |
NdefFormatable |
عملیات قالببندی را برای برچسبهایی که ممکن است قابلقالببندی NDEF باشند ارائه میدهد. |
دستگاههای مجهز به Android ملزم به پشتیبانی از فناوریهای برچسب زیر نیستند.
جدول ۲. فناوریهای برچسب پشتیبانیشده اختیاری
| کلاس | شرح |
|---|---|
MifareClassic |
اگر این دستگاه Android از MIFARE پشتیبانی کند، دسترسی به ویژگیهای MIFARE Classic و عملیات ورودی/خروجی را فراهم میکند. |
MifareUltralight |
اگر این دستگاه Android از MIFARE پشتیبانی کند، دسترسی به ویژگیهای MIFARE Ultralight و عملیات ورودی/خروجی را فراهم میکند. |
کار با فناوریهای برچسب و هدف ACTION_TECH_DISCOVERED
وقتی دستگاهی برچسبی را اسکن میکند که دادههای NDEF دارد اما نمیتواند به MIME یا URI نگاشت شود،
سیستم ارسال برچسب سعی میکند فعالیتی را با هدف ACTION_TECH_DISCOVERED
شروع کند. وقتی برچسبی با دادههای غیرNDEF اسکن میشود، از ACTION_TECH_DISCOVERED نیز استفاده میشود. داشتن این جایگزین به شما امکان میدهد مستقیماً با دادههای روی برچسب کار کنید
اگر سیستم ارسال برچسب نتواند آن را برای شما تجزیه کند. مراحل اصلی هنگام کار با فناوریهای برچسب به شرح زیر است:
- فیلتر کردن برای هدف
ACTION_TECH_DISCOVEREDکه فناوریهای برچسبی را که میخواهید مدیریت کنید مشخص میکند. برای اطلاعات بیشتر، به فیلتر کردن برای هدفهای NFC مراجعه کنید. بهطور کلی، سیستم ارسال برچسب سعی میکند وقتی پیام NDEF نمیتواند به نوع MIME یا URI نگاشت شود، یا اگر برچسب اسکنشده حاوی دادههای NDEF نباشد، هدفACTION_TECH_DISCOVEREDرا شروع کند. برای اطلاعات بیشتر درباره نحوه تعیین این موضوع، سیستم ارسال برچسب را ببینید. - وقتی برنامهتان هدف را دریافت میکند، شیء
Tagرا از هدف دریافت کنید:کاتلین
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
جاوا
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- با فراخوانی یکی از روشهای کارخانه
getکلاسها در بستهandroid.nfc.tech، نمونهای ازTagTechnologyرا دریافت کنید. میتوانید با فراخوانیgetTechList()قبلاز فراخوانی روش کارخانهget، فناوریهای پشتیبانیشده برچسب را فهرست کنید. برای مثال، برای دریافت نمونهای ازMifareUltralightازTag، کارهای زیر را انجام دهید:کاتلین
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
جاوا
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
خواندن و نوشتن در برچسبها
خواندن و نوشتن در برچسب NFC شامل دریافت برچسب از قصد و باز کردن ارتباط با برچسب است. باید پشته پروتکل خودتان را برای خواندن و نوشتن دادهها در برچسب تعریف کنید. بااینحال، بهخاطر داشته باشید که هنگام کار مستقیم با برچسب، همچنان میتوانید دادههای NDEF را بخوانید و بنویسید. اینکه چگونه میخواهید چیزها را ساختاربندی کنید به شما بستگی دارد. مثال زیر نحوه کار با برچسب MIFARE Ultralight را نشان میدهد.
کاتلین
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; } }
استفاده از سیستم ارسال پیشزمینه
سیستم ارسال پیشزمینه به یک فعالیت اجازه میدهد تا یک intent را رهگیری کند و ادعا کند اولویت نسبت به سایر فعالیتهایی که همان intent را انجام میدهند. استفاده از این سیستم شامل ساخت چند ساختار داده برای سیستم Android است تا بتواند هدفهای مناسب را به برنامه شما ارسال کند. برای فعال کردن سیستم ارسال پیشزمینه:
- کد زیر را در روش
onCreate()فعالیتتان اضافه کنید:- شیء
PendingIntentتغییرپذیری ایجاد کنید تا سیستم Android بتواند آن را با جزئیات برچسب هنگام اسکن شدن پر کند.کاتلین
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);
- فیلترهای قصد را برای رسیدگی به قصدهایی که میخواهید رهگیری کنید اعلام کنید. سیستم ارسال پیشزمینه، فیلترهای قصد مشخصشده را با قصدی که هنگام اسکن برچسب توسط دستگاه دریافت میشود بررسی میکند. اگر مطابقت داشته باشد، برنامه شما قصد را مدیریت میکند. اگر مطابقت نداشته باشد، سیستم ارسال پیشزمینه به سیستم ارسال هدف برمیگردد.
مشخص کردن آرایه
nullاز فیلترهای قصد و فیلترهای فناوری مشخص میکند که میخواهید همه برچسبهایی را که به قصدTAG_DISCOVEREDبرمیگردند فیلتر کنید. تکهکد زیر همه انواع MIME را برایNDEF_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()را فراخوانی کنید.کاتلین
techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
جاوا
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
- شیء
- فراخوانیهای برگشتی چرخه حیات فعالیت زیر را لغو کنید و منطقی را برای فعال و غیرفعال کردن
ارسال پیشزمینه هنگام ازدست رفتن (
onPause()) و بهدست آوردن مجدد (onResume()) تمرکز فعالیت اضافه کنید. enableForegroundDispatch()باید از رشته اصلی و فقط زمانی فراخوانی شود که فعالیت در پیشزمینه باشد (فراخوانی درonResume()این را تضمین میکند). همچنین باید فراخوانی برگشتیonNewIntentرا برای پردازش دادههای برچسب NFC اسکنشده پیادهسازی کنید.
کاتلین
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 }