این سند موضوعات پیشرفته NFC را توصیف میکند، مانند کار با فناوریهای برچسبهای مختلف، نوشتن روی برچسبهای NFC، و ارسال پیشزمینه، که به برنامهای در پیشزمینه اجازه میدهد حتی زمانی که برنامههای دیگر برای همان موارد فیلتر میکنند، مقاصد را مدیریت کند.
با فناوری های برچسب پشتیبانی شده کار کنید
هنگام کار با تگ های NFC و دستگاه های مجهز به اندروید، فرمت اصلی که برای خواندن و نوشتن داده ها روی برچسب ها استفاده می کنید NDEF است. هنگامی که یک دستگاه یک برچسب را با داده های NDEF اسکن می کند، Android از تجزیه پیام و ارائه آن در NdefMessage
در صورت امکان پشتیبانی می کند. با این حال، مواردی وجود دارد که برچسبی را اسکن میکنید که حاوی دادههای NDEF نیست یا زمانی که دادههای NDEF نمیتوانند به یک نوع MIME یا URI نگاشت شوند. در این موارد، باید ارتباط مستقیم با تگ را باز کنید و با پروتکل خود (در بایت های خام) آن را بخوانید و بنویسید. Android پشتیبانی عمومی را برای این موارد استفاده با بسته 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 | در صورتی که این دستگاه Android از MIFARE پشتیبانی کند، امکان دسترسی به ویژگیهای MIFARE Classic و عملیات ورودی/خروجی را فراهم میکند. |
MifareUltralight | در صورتی که این دستگاه اندرویدی از MIFARE پشتیبانی کند، امکان دسترسی به ویژگی های MIFARE Ultralight و عملیات I/O را فراهم می کند. |
با فناوریهای برچسب و هدف ACTION_TECH_DISCOVERED کار کنید
وقتی دستگاهی برچسبی را اسکن میکند که دادههای NDEF روی آن است، اما نمیتوان آن را به یک MIME یا URI نگاشت، سیستم ارسال برچسب تلاش میکند تا فعالیتی را با هدف ACTION_TECH_DISCOVERED
شروع کند. ACTION_TECH_DISCOVERED
همچنین هنگامی که یک برچسب با داده های غیر NDEF اسکن می شود استفاده می شود. اگر سیستم ارسال برچسب نتواند آن را برای شما تجزیه کند، داشتن این بازگشت به شما امکان می دهد مستقیماً با داده های روی برچسب کار کنید. مراحل اساسی هنگام کار با فناوری های برچسب به شرح زیر است:
- فیلتر برای یک هدف
ACTION_TECH_DISCOVERED
که فناوریهای برچسبی را که میخواهید مدیریت کنید مشخص میکند. برای اطلاعات بیشتر به فیلتر کردن اهداف NFC مراجعه کنید. به طور کلی، زمانی که یک پیام NDEF نمی تواند به یک نوع MIME یا URI نگاشت شود، یا اگر برچسب اسکن شده حاوی داده های NDEF نباشد، سیستم ارسال برچسب سعی می کند یک هدفACTION_TECH_DISCOVERED
را شروع کند. برای اطلاعات بیشتر در مورد چگونگی تعیین این، به سیستم ارسال برچسب مراجعه کنید. - هنگامی که برنامه شما intent را دریافت کرد، شی
Tag
را از intent دریافت کنید:کاتلین
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
جاوا
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- با فراخوانی یکی از متدهای
get
کارخانه کلاس ها در بستهandroid.nfc.tech
، نمونه ای ازTagTechnology
را دریافت کنید. قبل از فراخوانی متدget
factory می توانید فناوری های پشتیبانی شده تگ را با فراخوانیgetTechList()
برشمارید. به عنوان مثال، برای به دست آوردن یک نمونه از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; } }
از سیستم اعزام پیش زمینه استفاده کنید
سیستم ارسال پیشزمینه به یک فعالیت اجازه میدهد تا یک هدف را رهگیری کند و نسبت به سایر فعالیتهایی که همان هدف را مدیریت میکنند، اولویت داشته باشد. استفاده از این سیستم شامل ساخت چند ساختار داده برای سیستم اندروید است تا بتواند مقاصد مناسب را به برنامه شما ارسال کند. برای فعال کردن سیستم ارسال پیش زمینه:
- کد زیر را در متد
onCreate()
فعالیت خود اضافه کنید:- یک شی
PendingIntent
قابل تغییر ایجاد کنید تا سیستم اندروید بتواند آن را با جزئیات برچسب در هنگام اسکن پر کند.کاتلین
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()
این را تضمین می کند). همچنین برای پردازش دادهها از تگ NFC اسکن شده، نیاز به اجرای callbackonNewIntent
دارید.
کاتلین
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 }