يوضِّح هذا المستند مواضيع متقدّمة عن تقنية NFC، مثل استخدام تكنولوجيات مختلفة للعلامات، والكتابة إلى علامات NFC، والإرسال في المقدّمة، ما يسمح للتطبيق الذي يعمل في المقدّمة بمعالجة الأهداف حتى عندما تستخدم التطبيقات الأخرى الفلاتر نفسها.
العمل باستخدام تقنيات العلامات المتوافقة
عند التعامل مع علامات NFC والأجهزة التي تعمل بنظام التشغيل Android، يكون التنسيق الرئيسي الذي تستخدمه لقراءة البيانات وكتابتها على العلامات هو 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) وعمليات وحدات الإدخال والإخراج. |
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 |
يوفّر إمكانية الوصول إلى خصائص MIFARE الكلاسيكية وعمليات وحدات الإدخال والإخراج، إذا كان جهاز Android هذا متوافقًا مع MIFARE. |
MifareUltralight |
يوفّر إمكانية الوصول إلى خصائص MIFARE Ultralight وعمليات وحدات الإدخال والإخراج، إذا كان جهاز Android هذا متوافقًا مع معيار MIFARE. |
العمل باستخدام تقنيات العلامات والإجراء ACTION_TECH_DISCOVERED
عندما يفحص جهاز علامة تتضمّن بيانات NDEF، ولكن يتعذّر ربطها ببروتوكول MIME أو معرّف الموارد المنتظم (URI)،
يحاول نظام إرسال العلامة بدء نشاط بقصد ACTION_TECH_DISCOVERED
. تُستخدم ACTION_TECH_DISCOVERED
أيضًا عند فحص علامة تحتوي على بيانات غير NDEF. يتيح لك إجراء هذا الإجراء الاحتياطي العمل على البيانات في العلامة مباشرةً إذا لم يتمكّن نظام إرسال العلامة من تحليلها نيابةً عنك. في ما يلي الخطوات الأساسية عند استخدام
تقنيات العلامات:
- طبِّق الفلتر بحثًا عن هدف
ACTION_TECH_DISCOVERED
يحدّد تقنيات العلامات التي تريد معالجتها. راجع التصفية بحثًا عن نية استخدام NFC لمزيد من المعلومات. بشكل عام، يحاول نظام إرسال العلامات بدء هدفACTION_TECH_DISCOVERED
عندما يتعذّر ربط رسالة NDEF بنوع MIME أو معرّف موارد منتظم (URI)، أو إذا لم تكن العلامة التي تم فحصها تحتوي على بيانات NDEF. ولمزيد من المعلومات عن كيفية تحديد ذلك، راجِع نظام إرسال العلامات. - عندما يتلقّى تطبيقك عنصر intent، احصل على الكائن
Tag
من سمة intent:Kotlin
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- احصل على نسخة افتراضية من
TagTechnology
من خلال استدعاء إحدى أساليبget
المصنعة للفئات في حزمةandroid.nfc.tech
. يمكنك تعداد التكنولوجيات المتوافقة للعلامة عن طريق استدعاءgetTechList()
قبل طلبget
بطريقة المصنع. على سبيل المثال، للحصول على مثيلMifareUltralight
منTag
، يُرجى اتّباع الخطوات التالية:Kotlin
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
Java
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
قراءة العلامات والكتابة فيها
وتتضمن القراءة والكتابة في علامة NFC الحصول على العلامة من قصدها وفتح الاتصال بها. عليك تحديد حزمة البروتوكول الخاصة بك لقراءة البيانات وكتابتها في العلامة. مع ذلك، ضع في اعتبارك أنه لا يزال بإمكانك قراءة بيانات NDEF وكتابتها عند العمل مباشرةً باستخدام العلامة. الأمر متروك لك في كيفية هيكلة الأشياء. يوضح المثال التالي كيفية التعامل مع علامة 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; } }
استخدام نظام الإرسال في المقدّمة
يسمح نظام الإرسال الذي يعمل في المقدّمة لنشاط باعتراض هدف وادّعاء الأولوية على الأنشطة الأخرى التي تعالج الهدف نفسه. ويتضمّن استخدام هذا النظام إنشاء بعض بُنى البيانات لنظام Android كي يتمكّن من إرسال الأغراض المناسبة إلى تطبيقك. لتفعيل نظام الإرسال في المقدّمة:
- أضِف الرمز التالي في طريقة
onCreate()
لنشاطك:- أنشِئ عنصر
PendingIntent
قابلاً للتغيير حتى يتمكّن نظام Android من تعبئته بتفاصيل العلامة عند فحصها.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);
- حدِّد فلاتر الأهداف للتعامل مع الأهداف التي تريد اعتراضها. يتحقّق نظام الإرسال الذي يعمل في المقدّمة من فلاتر الأهداف المحدّدة بهدف تلقّيه عندما يفحص الجهاز إحدى العلامات. وفي حال التطابق، سيعالج التطبيق الغرض. وفي حال عدم التطابق، يعود نظام الإرسال في المقدّمة إلى نظام إرسال الأهداف.
يؤدي تحديد مصفوفة
null
من فلاتر الأهداف وفلاتر التكنولوجيا إلى تحديد الحاجة إلى فلترتها لجميع العلامات التي تتراجع عن استخدام هدفTAG_DISCOVERED
. يتعامل مقتطف الرمز أدناه مع جميع أنواع MIME لـNDEF_DISCOVERED
. يجب معالجة الطلبات التي تحتاج إليها فقط.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, };
- عليك إعداد مصفوفة من تقنيات العلامات التي يريد تطبيقك معالجتها. وعليك استدعاء الطريقة
Object.class.getName()
للحصول على فئة التكنولوجيا التي تريد استخدامها.Kotlin
techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
Java
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
- أنشِئ عنصر
- يمكنك إلغاء استدعاءات مراحل نشاط النشاط التالية وإضافة منطق لتفعيل إرسال البيانات في المقدّمة أو إيقافه عند فقدان النشاط (
onPause()
) واستعادة التركيز (onResume()
). يجب استدعاءenableForegroundDispatch()
من سلسلة التعليمات الرئيسية، وعندما يكون النشاط في المقدّمة فقط (يضمن استدعاء الدالةonResume()
ذلك). عليك أيضًا تنفيذ استدعاءonNewIntent
لمعالجة البيانات من علامة NFC الممسوحة ضوئيًا.
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 }