يصف هذا المستند المهام الأساسية لتقنية NFC التي تُجريها في Android. ويشرح هذا الدليل كيفية إرسال بيانات NFC وتلقّيها في شكل رسائل NDEF، ويوضّح واجهات برمجة التطبيقات لإطار عمل Android التي تتيح هذه الميزات. لمزيد من المواضيع المتقدّمة، بما في ذلك مناقشة حول التعامل مع البيانات غير المتوافقة مع معيار NDEF، راجِع التعامل المتقدّم مع تقنية NFC.
تتم معالجة قراءة بيانات NDEF من علامة NFC باستخدام نظام إرسال العلامات الذي يحلّل علامات NFC التي تم رصدها ويصنّف البيانات بشكل مناسب ويبدأ تطبيقًا مهتمًا بالبيانات المصنّفة. يمكن للتطبيق الذي يريد معالجة علامة NFC التي تم مسحها ضوئيًا تحديد فلتر الغرض و طلب معالجة البيانات.
نظام إرسال العلامات
تبحث الأجهزة التي تعمل بنظام التشغيل Android عادةً عن علامات NFC عندما يكون شاشة الجهاز مفتوحة، ما لم يتم إيقاف تقنية NFC في قائمة "الإعدادات" على الجهاز. عندما يكتشف جهاز Android علامة NFC، يكون السلوك المطلوب هو أن يعالج النشاط الأنسب النية بدون أن يسأل المستخدم عن التطبيق الذي يريده. بما أنّ الأجهزة تفحص علامات NFC على نطاق قصير جدًا، من المرجّح أن يؤدي توجيه المستخدمين إلى اختيار نشاط يدويًا إلى إبعاد الجهاز عن العلامة وقطع الاتصال. عليك تطوير نشاطك ليتعامل فقط مع علامات NFC التي يهتم بها نشاطك لمنع ظهور "أداة اختيار الأنشطة".
لمساعدتك في تحقيق هذا الهدف، يقدّم نظام التشغيل Android نظام إرسال علامات خاصًا يحلّل علامات فاقِد الذاكرة اللاسلكي (NFC) التي تم فحصها ويحلّلها ويحاول تحديد موقع التطبيقات المهتمة بالبيانات التي تم فحصها. ويهدف إلى تحقيق ذلك من خلال:
- تحليل علامة NFC وتحديد نوع MIME أو معرّف الموارد المنتظم (URI) الذي يحدِّد الحمولة البيانات في العلامة
- تجميع نوع MIME أو معرّف الموارد المنتظم (URI) وحمولة البيانات في نية تم وصف هاتين الخطوتَين الأولى في مقالة كيفية ربط علامات NFC بأنواع MIME ومعرّفات الموارد المنتظمة (URI).
- يبدأ نشاطًا استنادًا إلى النية. يُرجى الاطّلاع على مزيد من المعلومات في مقالة كيفية إرسال علامات NFC إلى التطبيقات.
كيفية ربط علامات NFC بأنواع MIME وعناوين URL
قبل البدء في كتابة تطبيقات NFC، من المهم فهم الأنواع المختلفة لعلامات NFC وكيفية تحليل نظام إرسال العلامات لعلامات NFC والعمل الخاص الذي يؤديه نظام إرسال العلامات عند رصد رسالة NDEF. تتوفّر علامات NFC في مجموعة كبيرة من التقنيات، ويمكن أيضًا كتابة البيانات عليها بعدة طرق مختلفة. يتوافق نظام Android مع معيار NDEF بشكل أكبر من أي نظام تشغيل آخر، وهو المعيار الذي حدّده منتدى NFC.
يتم تضمين بيانات NDEF داخل رسالة (NdefMessage
) تحتوي على سجلّ واحد
أو أكثر (NdefRecord
). يجب أن يكون كل سجلّ NDEF منسقًا بشكل جيد وفقًا
لمواصفات نوع السجلّ الذي تريد إنشاؤه. يتيح نظام التشغيل Android
أيضًا أنواعًا أخرى من العلامات التي لا تحتوي على بيانات NDEF، ويمكنك التعامل معها باستخدام
الفئات في حزمة android.nfc.tech
. لمزيد من المعلومات
حول هذه التقنيات، اطّلِع على موضوع التقنيات المتقدّمة لتقنية NFC. يتطلّب العمل مع هذه الأنواع الأخرى من العلامات
كتابة حِزمة بروتوكولك الخاص للتواصل مع العلامات، لذا ننصحك باستخدام NDEF كلما أمكن ذلك لتسهيل عملية التطوير وتوفير أكبر قدر ممكن من التوافق مع الأجهزة التي تعمل بنظام التشغيل Android.
ملاحظة: لتنزيل مواصفات NDEF الكاملة، انتقِل إلى الموقع الإلكتروني NFC Forum Specifications & Application Documents (مواصفات منتدى NFC ومستندات التطبيقات) واطّلِع على Creating common types of NDEF records (إنشاء أنواع شائعة من سجلّات NDEF) للحصول على أمثلة حول كيفية إنشاء سجلّات NDEF.
بعد أن حصلت على بعض المعلومات الأساسية عن علامات NFC، توضّح الأقسام التالية بمزيد من التفصيل كيفية تعامل نظام Android مع العلامات بتنسيق NDEF. عندما يفحص جهاز Android علامة NFC تحتوي على بيانات بتنسيق NDEF، فإنه يحلّل الرسالة ويحاول معرفة نوع MIME للبيانات أو تحديد
معرّف URI. لإجراء ذلك، يقرأ النظام العنصر NdefRecord
الأول داخل العنصر NdefMessage
لتحديد كيفية تفسير رسالة NDEF بالكامل (يمكن أن تحتوي رسالة NDEF على عدة سجلات NDEF). في رسالة NDEF ذات التنسيق الصحيح، يحتوي العنصر NdefRecord
الأول على الحقول التالية:
- TNF (تنسيق اسم النوع) المكوّن من 3 بت
- يشير إلى كيفية تفسير حقل النوع الذي يتغيّر طوله. القيم الصالحة описаны в Таблице 1.
- نوع الطول المتغيّر
- يصف نوع السجلّ. في حال استخدام
TNF_WELL_KNOWN
، استخدِم هذا الحقل لتحديد تعريف نوع السجلّ (RTD). يتم وصف قيم RTD الصالحة في الجدول 2. - معرّف بطول متغيّر
- معرّف فريد للسجلّ لا يتم استخدام هذا الحقل كثيرًا، ولكن إذا كنت بحاجة إلى تحديد علامة بشكل فريد، يمكنك إنشاء معرّف لها.
- حمولة ذات طول متغيّر
- حمولة البيانات الفعلية التي تريد قراءتها أو كتابتها يمكن أن تحتوي رسالة NDEF على عدة سجلّات NDEF، لذا لا تفترض أنّ الحمولة الكاملة متوفّرة في أول سجلّ NDEF لرسالة NDEF.
يستخدم نظام إرسال العلامات حقلَي TNF وtype لمحاولة ربط نوع MIME أو معرّف موارد منتظم (URI) برسالة NDEF. وفي حال نجاح ذلك، يتم تضمين هذه المعلومات داخل نية ACTION_NDEF_DISCOVERED
مع الحمولة الفعلية. ومع ذلك، هناك
حالات لا يستطيع فيها نظام إرسال العلامات تحديد نوع البيانات استنادًا إلى أول سجلّ NDEF. يحدث ذلك عندما يتعذّر ربط بيانات NDEF بنوع MIME أو عنوان URL، أو عندما لا تحتوي علامة
NFC على بيانات NDEF في الأساس. في هذه الحالات، يتم تجميع عنصر Tag
يحتوي على معلومات عن تكنولوجيات العلامة وحمولتها
داخل نية ACTION_TECH_DISCOVERED
بدلاً من ذلك.
يوضِّح الجدول 1 كيفية ربط نظام إرسال العلامات لحقول TNF وtype
بأنواع MIME أو معرّفات الموارد المنتظمة (URI). ويوضّح أيضًا أنواع TNF التي لا يمكن ربطها بنوع MIME أو عنوان URL.
وفي هذه الحالات، يعود نظام إرسال العلامات إلى
ACTION_TECH_DISCOVERED
.
على سبيل المثال، إذا صادف نظام إرسال العلامات سجلًا من النوع TNF_ABSOLUTE_URI
، سيربط حقل نوع الطول المتغير لذلك السجل
بعنوان URL. يُغلِّف نظام إرسال العلامات معرّف الموارد المنتظم هذا في حقل البيانات لطلب ACTION_NDEF_DISCOVERED
مع معلومات أخرى عن العلامة،
مثل الحمولة. من ناحية أخرى، إذا صادف السجلّ نوع TNF_UNKNOWN
، سينشئ نية تُحاط بتكنولوجيات العلامة
بدلاً من ذلك.
الجدول 1: معرّفات TNF المتوافقة وعمليات الربط الخاصة بها
تنسيق اسم النوع (TNF) | التعيين |
---|---|
TNF_ABSOLUTE_URI |
عنوان URL استنادًا إلى حقل النوع |
TNF_EMPTY |
تنخفض إلى ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
معرّف الموارد المنتظم (URI) استنادًا إلى معرّف الموارد الموحّد (URN) في حقل النوع يتم ترميز معرّف URN في حقل نوع NDEF بأحد يليه:
شكل مختصر: <domain_name>:<service_name> .
يربط Android هذا العنوان بمعرّف URI على النحو التالي:
vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA |
نوع MIME استنادًا إلى حقل النوع |
TNF_UNCHANGED |
غير صالح في السجلّ الأول، لذا يتم الرجوع إلى
ACTION_TECH_DISCOVERED . |
TNF_UNKNOWN |
تنخفض إلى ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
نوع MIME أو معرّف الموارد المنتظم (URI) استنادًا إلى تعريف نوع السجلّ (RTD) الذي تحدّده في حقل type اطّلِع على الجدول 2 للحصول على مزيد من المعلومات عن التقارير المتوفّرة للاطّلاع على بيانات الأرباح وعمليات الربط الخاصة بها. |
الجدول 2: جداول بيانات الردّ الجاهزة المتوافقة مع TNF_WELL_KNOWN وعمليات الربط
تعريف نوع السجلّ (RTD) | التعيين |
---|---|
RTD_ALTERNATIVE_CARRIER |
تنخفض إلى ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
تنخفض إلى ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
تنخفض إلى ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
تنخفض إلى ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
عنوان URL يستند إلى تحليل الحمولة |
RTD_TEXT |
نوع MIME text/plain |
RTD_URI |
عنوان URL يستند إلى الحمولة |
كيفية إرسال علامات NFC إلى التطبيقات
عندما ينتهي نظام إرسال العلامات من إنشاء نية تتضمن علامة NFC ومعلومات تحديد هويتها، يرسل هذه النية إلى تطبيق مهتم بها يُجري تصفية للبحث عن هذه النية. إذا كان بإمكان أكثر من تطبيق واحد معالجة النية، يتم عرض "أداة اختيار الأنشطة" ليتمكّن المستخدم من اختيار النشاط. يحدِّد نظام إرسال العلامات ثلاثة أهداف، وهي مُدرَجة بترتيب من الأعلى إلى الأدنى من حيث الأولوية:
-
ACTION_NDEF_DISCOVERED
: يُستخدَم هذا الإجراء لبدء نشاط عند مسح علامة تحتوي على حمولة NDEF وتكون من نوع معروف ضوئيًا. هذا هو الهدف الأعلى أولوية، ويحاول نظام إرسال العلامات بدء نشاط باستخدام هذا الهدف قبل أي هدف آخر، كلما أمكن ذلك.ملاحظة: اعتبارًا من الإصدار 16 من نظام التشغيل Android، سيؤدي مسح علامات NFC التي تخزِّن روابط عناوين URL (أي مخطّط URI هو "htttps://" أو "http://") إلى بدء الإجراء
ACTION_VIEW
بدلاً من الإجراءACTION_NDEF_DISCOVERED
. ACTION_TECH_DISCOVERED
: إذا لم يتم تسجيل أي أنشطة لمعالجةACTION_NDEF_DISCOVERED
intent، يحاول نظام إرسال العلامات بدء تطبيق باستخدام هذا الintent. يبدأ هذا القصد أيضًا مباشرةً (بدون بدءACTION_NDEF_DISCOVERED
أولاً) إذا كانت العلامة التي يتم مسحها ضوئيًا تحتوي على بيانات NDEF لا يمكن ربطها بنوع MIME أو عنوان URL، أو إذا كانت العلامة لا تحتوي على بيانات NDEF ولكنها من تكنولوجيا علامة معروفة.ACTION_TAG_DISCOVERED
: يتم بدء هذا النيّة إذا لم تكن هناك أنشطة تعالج نيتَيACTION_NDEF_DISCOVERED
أوACTION_TECH_DISCOVERED
.
في ما يلي الطريقة الأساسية التي يعمل بها نظام إرسال العلامات:
- حاوِل بدء نشاط باستخدام النية التي أنشأها نظام إرسال العلامات عند تحليل علامة NFC (إما
ACTION_NDEF_DISCOVERED
أوACTION_TECH_DISCOVERED
). - إذا لم يتم فلترة أي أنشطة لهذا الغرض، حاوِل بدء نشاط باستخدام المحاولة التالية
الغرض الأقلّ أولوية (إما
ACTION_TECH_DISCOVERED
أوACTION_TAG_DISCOVERED
) إلى أن يفرِّط أحد التطبيقات في البحث عن الغرض أو إلى أن يحاول نظام إرسال العلامات جميع الأغراض المحتمَلة. - إذا لم تكن هناك تطبيقات لفلترة أيّ من النوايا، لا داعي لإجراء أيّ شيء.

استخدِم رسائل NDEF وهدف ACTION_NDEF_DISCOVERED
كلما أمكن، لأنّه الأكثر تحديدًا من بين
الثلاثة. يتيح لك هذا الإجراء بدء تطبيقك في وقت أكثر ملاءمةً مقارنةً بالهدفين
الآخرين، ما يمنح المستخدم تجربة أفضل.
طلب الوصول إلى تقنية NFC في بيان Android
قبل أن تتمكّن من الوصول إلى أجهزة NFC في الجهاز ومعالجة نوايا NFC بشكل صحيح، عليك الإفصاح عن
هذه العناصر في ملف AndroidManifest.xml
:
- عنصر NFC
<uses-permission>
للوصول إلى جهاز NFC:<uses-permission android:name="android.permission.NFC" />
- الحد الأدنى لإصدار حزمة تطوير البرامج (SDK) الذي يمكن لتطبيقك استخدامه. لا يتيح مستوى واجهة برمجة التطبيقات 9 سوى
إرسال علامات محدود عبر
ACTION_TAG_DISCOVERED
، ولا يتيح سوى الوصول إلى رسائل NDEF عبر الإضافةEXTRA_NDEF_MESSAGES
. لا يمكن الوصول إلى أيّ من سمات العلامة أو عمليات الإدخال/الإخراج الأخرى. يتضمّن المستوى 10 لواجهة برمجة التطبيقات دعمًا شاملاً للقارئ/الكاتب بالإضافة إلى ميزة دفع NDEF في المقدّمة، ويقدّم المستوى 14 لواجهة برمجة التطبيقات طُرقًا إضافية لتسهيل إنشاء سجلّات NDEF.<uses-sdk android:minSdkVersion="10"/>
- عنصر
uses-feature
لعرض تطبيقك في Google Play للأجهزة التي تتضمّن أجهزة اتصال بالحقل القريب فقط:<uses-feature android:name="android.hardware.nfc" android:required="true" />
إذا كان تطبيقك يستخدم وظيفة NFC، ولكن هذه الوظيفة ليست ضرورية لتطبيقك، يمكنك حذف العنصر
uses-feature
والتحقّق من توفّر NFC أثناء وقت التشغيل من خلال التحقّق ممّا إذا كانgetDefaultAdapter()
null
.
فلترة طلبات NFC
لبدء تطبيقك عند مسح علامة NFC تريد التعامل معها ضوئيًا، يمكن لتطبيقك
فلترة طلب واحد أو طلبَين أو الطلبَين الثالثَين من طلبات NFC في ملف بيان Android. ومع ذلك، عادةً ما تريد فلترة البيانات حسب النية ACTION_NDEF_DISCOVERED
للتحكم بشكلٍ أكبر في وقت بدء تطبيقك. يُعدّ هدف ACTION_TECH_DISCOVERED
بديلاً لهدف ACTION_NDEF_DISCOVERED
عندما لا تفلتر أي تطبيقات ACTION_NDEF_DISCOVERED
أو عندما لا تكون الحمولة ملفًا بتنسيق NDEF. عادةً ما تكون فئة ACTION_TAG_DISCOVERED
عامة جدًا ولا يمكن فلترة البيانات استنادًا إليها. ستتم فلترة العديد من التطبيقات بحثًا عن ACTION_NDEF_DISCOVERED
أو ACTION_TECH_DISCOVERED
قبل ACTION_TAG_DISCOVERED
، لذا منخفض احتمال أن يبدأ تطبيقك. لا يتوفّر ACTION_TAG_DISCOVERED
إلا كحلّ أخير
للتطبيقات التي تريد الفلترة في الحالات التي لا يتم فيها تثبيت تطبيقات أخرى لمعالجة ACTION_NDEF_DISCOVERED
أو ACTION_TECH_DISCOVERED
.
لا يمكن تنفيذ ذلك في بعض الأحيان لأنّ عمليات نشر علامات NFC تختلف ولا تخضع أحيانًا للتحكّم، ولهذا السبب يمكنك الرجوع إلى الغرضَين الآخرين عند الضرورة. عندما يكون بإمكانك التحكّم في أنواع العلامات والبيانات المكتوبة، ننصحك باستخدام NDEF لتنسيق علاماتك. توضّح الأقسام التالية كيفية الفلترة حسب كل نوع من أنواع الأهداف.
ACTION_NDEF_DISCOVERED
لفلترة البيانات حسب نوايا ACTION_NDEF_DISCOVERED
، عليك الإفصاح عن
فلتر النية مع نوع البيانات التي تريد الفلترة حسبها. في المثال التالي، يتمّ فلترة ACTION_NDEF_DISCOVERED
الطلبات التي يكون نوع 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>
تصفّح المثال التالي عن عنوان URL بالتنسيق التالي:
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
إذا كان نشاطك يُفلتر حسب النية ACTION_TECH_DISCOVERED
،
عليك إنشاء ملف موارد XML يحدّد التقنيات التي يتيحها نشاطك
ضمن مجموعة tech-list
. يُعتبَر نشاطك
مطابقًا إذا كانت مجموعة tech-list
هي مجموعة فرعية من التقنيات التي
تتيحها العلامة، والتي يمكنك الحصول عليها من خلال الاتصال بـ getTechList()
.
على سبيل المثال، إذا كانت العلامة التي يتم مسحها ضوئيًا متوافقة مع MifareClassic وNdefFormatable وNfcA، يجب أن تحدِّد مجموعة
tech-list
كل التقنيات الثلاث أو اثنتين أو واحدة (وليس
غيرها) لكي تتم مطابقة نشاطك.
يحدِّد النموذج التالي جميع التكنولوجيات. يجب إزالة البطاقات التي لا تتعايش
مع علامة NFC. احفظ هذا الملف (يمكنك تسميته بأي اسم تريده) في المجلد
<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>
يمكنك أيضًا تحديد مجموعات tech-list
متعددة. يتمّ التعامل مع كلّ مجموعة من tech-list
بشكلٍ مستقلّ، ويتمّ اعتبار نشاطك مطابقًا إذا كانت أيّ مجموعة واحدة
tech-list
هي مجموعة فرعية من التقنيات التي يعرضها getTechList()
. يقدّم ذلك دلالات AND
وOR
لتقنيات المطابقة. يطابق المثال التالي العلامات التي يمكنها استخدام تكنولوجيات
NfcA وNdef أو تكنولوجيات NfcB و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>
في ملف AndroidManifest.xml
، حدِّد ملف الموارد الذي أنشأته للتو
في العنصر <meta-data>
داخل العنصر <activity>
كما هو موضّح في المثال التالي:
<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>
لمزيد من المعلومات عن التعامل مع تكنولوجيات العلامات وintent ACTION_TECH_DISCOVERED
، اطّلِع على العمل باستخدام
تكنولوجيات العلامات المتوافقة في مستند NFC المتقدّم.
ACTION_TAG_DISCOVERED
لفلترة النتائج حسب ACTION_TAG_DISCOVERED
، استخدِم فلتر القصد التالي:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
ACTION_VIEW
اعتبارًا من الإصدار 16 من نظام التشغيل Android، سيؤدي مسح علامات NFC التي تخزِّن روابط عناوين URL إلى تنشيط النية ACTION_VIEW
. لفلترة البيانات حسب ACTION_VIEW
يُرجى الرجوع إلى this
. استخدِم Android app links
لفتح تطبيقك لعنوان URL.
الحصول على معلومات من النوايا
إذا بدأ نشاط بسبب نية NFC، يمكنك الحصول على معلومات عن علامة NFC الممسوحة ضوئيًا من النية. يمكن أن تحتوي النوايا على الإضافات التالية استنادًا إلى العلامة التي تم مسحها ضوئيًا:
-
EXTRA_TAG
(سمة مطلوبة): عنصرTag
يمثّل العلامة الممسوحة ضوئيًا -
EXTRA_NDEF_MESSAGES
(اختياري): صفيف من رسائل NDEF تم تحليلها من العلامة هذه الإضافة إلزامية فيACTION_NDEF_DISCOVERED
intents. EXTRA_ID
(اختياري): رقم التعريف المنخفض المستوى للعلامة.
للحصول على هذه الإضافات، تحقّق ممّا إذا تم تشغيل نشاطك باستخدام أحد
المقصودات NFC لضمان مسح علامة ضوئيًا، ثم احصل على الإضافات من
المقصود. يتحقّق المثال التالي من طلب ACTION_NDEF_DISCOVERED
ويحصل على رسائل NDEF من عنصر إضافي للطلب.
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. ... } } }
بدلاً من ذلك، يمكنك الحصول على عنصر Tag
من الطلب، والذي سيتضمّن ملفّ الحمولة ويسمح لك بسرد تكنولوجيات العلامة:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
إنشاء أنواع شائعة من سجلات NDEF
يوضّح هذا القسم كيفية إنشاء الأنواع الشائعة من سجلّات NDEF لمساعدتك عند الكتابة في علامات NFC. بدءًا من Android 4.0 (المستوى 14 من واجهة برمجة التطبيقات)، تتوفّر الطريقة
createUri()
لمساعدتك في إنشاء
سجلّات عناوين URL تلقائيًا. بدءًا من الإصدار 4.1 من نظام التشغيل Android (المستوى 16 من واجهة برمجة التطبيقات)، يتوفّر الإصداران
createExternal()
وcreateMime()
لمساعدتك في إنشاء
سجلات MIME وسجلات NDEF من النوع الخارجي. استخدِم طرق المساعدة هذه كلما أمكن ذلك لتجنُّب الأخطاء عند إنشاء سجلّات NDEF يدويًا.
يوضّح هذا القسم أيضًا كيفية إنشاء ملف ترشيح ينطبق على السجلّ ويرتبط بالهدف. يجب أن تكون جميع أمثلة سجلّات NDEF هذه في أول سجلّ NDEF لرسالة NDEF التي تكتبها في علامة.
TNF_ABSOLUTE_URI
ملاحظة: ننصحك باستخدام نوع
RTD_URI
بدلاً
من TNF_ABSOLUTE_URI
، لأنّه أكثر فعالية.
يمكنك إنشاء سجلّ NDEF بتنسيق TNF_ABSOLUTE_URI
بالطريقة التالية:
:
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]);
سيبدو فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:
<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
يمكنك إنشاء سجلّ NDEF بتنسيق TNF_MIME_MEDIA
بالطُرق التالية:
باستخدام طريقة 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")));
إنشاء NdefRecord
يدويًا:
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")));
سيبدو فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:
<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 مع RTD_TEXT
يمكنك إنشاء سجلّ NDEF بتنسيق TNF_WELL_KNOWN
بالطريقة التالية:
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; }
سيبدو فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:
<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 مع RTD_URI
يمكنك إنشاء سجلّ NDEF بتنسيق TNF_WELL_KNOWN
بالطُرق التالية:
باستخدام طريقة createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
باستخدام طريقة 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);
إنشاء NdefRecord
يدويًا:
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);
سيبدو فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:
<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
يمكنك إنشاء سجلّ TNF_EXTERNAL_TYPE
NDEF بالطُرق التالية:
باستخدام طريقة 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);
إنشاء NdefRecord
يدويًا:
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);
سيبدو فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:
<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>
استخدِم TNF_EXTERNAL_TYPE
لعمليات نشر علامات NFC أكثر عمومية من أجل إتاحة استخدامها بشكل أفضل على كلٍّ من
الأجهزة التي تعمل بنظام التشغيل Android والأجهزة التي لا تعمل بنظام التشغيل Android.
ملاحظة: تتّبع عناوين URN الخاصة بـ TNF_EXTERNAL_TYPE
التنسيق الأساسي التالي:
urn:nfc:ext:example.com:externalType
، ومع ذلك، تنص مواصفات NFC Forum RTD
على أنّه يجب حذف الجزء urn:nfc:ext:
من عنوان URN من تسجيل NDEF. وبالتالي، ما عليك سوى تقديم النطاق (example.com
في المثال)
والنوع (externalType
في المثال) مفصولَين بنقطتَين رأسيتين.
عند إرسال TNF_EXTERNAL_TYPE
، يحوّل Android معرّف URN urn:nfc:ext:example.com:externalType
إلى معرّف URI vnd.android.nfc://ext/example.com:externalType
، وهو ما يُعلن عنه
فلتر الغرض في المثال.
سجلّات تطبيقات Android
تم تقديم "سجلّ تطبيقات Android" (AAR) في الإصدار 4.0 من نظام التشغيل Android (المستوى 14 لواجهة برمجة التطبيقات)، وهو يضمن بشكلٍ أفضل بدء تطبيقك عند مسح علامة NFC ضوئيًا. يحتوي ملف AAR على اسم الحزمة لتطبيق مضمّن داخل سجلّ NDEF. يمكنك إضافة سجلّ AAR إلى أي سجلّ NDEF في رسالتك بتنسيق NDEF، لأنّ Android يبحث في رسالة NDEF بالكامل عن سجلّات AAR. إذا عثر على ملف AAR، يبدأ التطبيق استنادًا إلى اسم الحزمة داخل ملف AAR. إذا لم يكن التطبيق متوفّرًا على الجهاز، سيتم تشغيل Google Play لتنزيل التطبيق.
تكون AAR مفيدة إذا كنت تريد منع التطبيقات الأخرى من الفلترة حسب النية نفسها وربما معالجة علامات معيّنة تم نشرها. لا تتوفّر AAR إلا على مستوى التطبيق، بسبب قيود اسم الحزمة، وليس على مستوى النشاط كما هو الحال مع فلترة الأهداف. إذا كنت تريد معالجة نية على مستوى النشاط، استخدِم فلاتر الأهداف.
إذا كانت العلامة تحتوي على AAR، يُرسِل نظام إرسال العلامات الرسالة بالطريقة التالية:
- حاوِل بدء نشاط باستخدام فلتر نية كالمعتاد. إذا كان النشاط الذي يتطابق مع النية يتطابق أيضًا مع AAR، ابدأ النشاط.
- إذا كان النشاط الذي يفرِّط في الطلب لا يتطابق مع AAR، أو إذا كان بإمكان أنشطة متعدّدة معالجة الطلب، أو إذا لم يكن هناك نشاط يعالج الطلب، ابدأ التطبيق المحدّد في AAR.
- إذا لم يكن بإمكان أي تطبيق بدء عملية باستخدام ملف AAR، انتقِل إلى Google Play لتنزيل التطبيق استنادًا إلى ملف AAR.
ملاحظة: يمكنك إلغاء عمليات AAR ونظام إرسال الإشارات باستخدام نظام إرسال في المقدّمة، ما يسمح للنشاط في المقدّمة بالحصول على الأولوية عند رصد علامة NFC. باستخدام هذه الطريقة، يجب أن يكون النشاط في المقدّمة لإلغاء عمليات تسجيل بيانات الاستخدام ونظام إرسال الإشارات.
إذا كنت لا تزال تريد الفلترة حسب العلامات الممسوحة ضوئيًا التي لا تحتوي على AAR، يمكنك الإفصاح عن فلاتر الأهداف كالمعتاد. يكون ذلك مفيدًا إذا كان تطبيقك مهتمًا بعلامات أخرى لا تحتوي على AAR. على سبيل المثال، قد تريد ضمان أن يتعامل تطبيقك مع العلامات المملوكة التي تنشرها بالإضافة إلى العلامات العامة التي تنشرها جهات خارجية. يُرجى العِلم أنّ ملفات AAR مخصّصة لأجهزة Android 4.0 أو الإصدارات الأحدث، لذا عند نشر العلامات، من المرجّح أن تحتاج إلى استخدام تركيبة من ملفات AAR وأنواع MIME/عناوين URL لتتوافق مع أكبر نطاق من الأجهزة. بالإضافة إلى ذلك، عند نشر علامات NFC، يجب التفكير في كيفية كتابة علامات NFC لتفعيل التوافق مع معظم الأجهزة (أجهزة Android والأجهزة الأخرى). ويمكنك إجراء ذلك من خلال تحديد نوع MIME أو عنوان URL فريدَين نسبيًا لتسهيل تمييز التطبيقات بينهما.
يوفّر Android واجهة برمجة تطبيقات بسيطة لإنشاء حِزم APK القابلة للاستبدال،
createApplicationRecord()
. ما عليك سوى
تضمين ملف AAR في أي مكان في NdefMessage
. لا تريد
استخدام السجلّ الأول من NdefMessage
، ما لم يكن سجلّ AAR هو السجلّ الوحيد
في NdefMessage
. ويعود السبب في ذلك إلى أنّ نظام Android
يتحقّق من السجلّ الأول من NdefMessage
لتحديد نوع MIME أو
عنوان URL للعلامة، والذي يتم استخدامه لإنشاء نية للتطبيقات لفلترة المحتوى. توضّح لك التعليمة البرمجية التالية كيفية إنشاء تقرير 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")} ); )
قائمة التطبيقات المسموح بها لمسح علامة NFC ضوئيًا
بدءًا من الإصدار 16 من نظام التشغيل Android، يتم إعلام المستخدمين عندما يتلقّى أحد التطبيقات طلب NFC الأول لفحص علامات NFC. يُتاح للمستخدم خيار عدم السماح للتطبيق بمسح علامات NFC ضوئيًا بعد ذلك في الإشعار.
- يمكن للتطبيقات التحقّق مما إذا كان
المستخدم قد سمح للتطبيق بمسح علامات NFC ضوئيًا باستخدام
NfcAdapter.isTagIntentAllowed()
. - يمكن للتطبيقات أن تطلب من المستخدم السماح بمسح علامة NFC ضوئيًا مرة أخرى من خلال إرسال النية
ACTION_CHANGE_TAG_INTENT_PREFERENCE
.
ملاحظة: يمكن الوصول إلى قائمة التطبيقات المسموح لها بمسح علامة NFC ضوئيًا ضمن Settings > Apps > Special app access > Launch via NFC
.