يصف هذا المستند المهام الأساسية لتقنية 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). ويتم توضيح قيم الوقت الفعلي الصالحة في الجدول 2. - معرّف بطول متغيّر
- معرّف فريد للسجلّ لا يتم استخدام هذا الحقل كثيرًا، ولكن إذا كنت بحاجة إلى تعريف علامة بشكل فريد، يمكنك إنشاء معرّف لها.
- الحمولة متغيّرة الطول
- حمولة البيانات الفعلية التي تريد قراءتها أو كتابتها. يمكن أن تحتوي رسالة NDEF على عدة سجلّات NDEF، لذا لا تفترض أنّ الحمولة الكاملة متوفّرة في أول سجلّ NDEF لرسالة NDEF.
يستخدم نظام إرسال العلامات حقلَي TNF والنوع لمحاولة ربط نوع 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
، يتم ربط حقل نوع السمة المتغيّر لهذا السجلّ بمعرّف موارد منتظم (URI). يتضمّن نظام إرسال العلامات معرّف الموارد المنتظم (URI) هذا في حقل بيانات الغرض ACTION_NDEF_DISCOVERED
إلى جانب معلومات أخرى عن العلامة،
مثل الحمولة. من ناحية أخرى، إذا صادف السجلّ نوع TNF_UNKNOWN
، سينشئ نية تُحاط بتكنولوجيات العلامة
بدلاً من ذلك.
تنسيق اسم النوع (TNF) | التعيين |
---|---|
TNF_ABSOLUTE_URI |
عنوان URL استنادًا إلى حقل النوع |
TNF_EMPTY |
يعود إلى ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
معرّف الموارد المنتظم (URI) استنادًا إلى معرّف الموارد الموحّد (URN) في حقل النوع يتم ترميز معرّف URN في حقل نوع NDEF بأحد يليه:
شكل مختصر: <domain_name>:<service_name> .
يربط Android هذا العنوان بمعرّف موارد منتظم على النحو التالي:
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 للحصول على مزيد من المعلومات عن التقارير المتوفّرة للاطّلاع على بيانات الأداء وعمليات الربط الخاصة بها. |
تعريف نوع السجلّ (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 وتكون من نوع معروف. هذا هو الهدف الأعلى أولوية، ويحاول نظام إرسال العلامات بدء نشاط باستخدام هذا الهدف قبل أي هدف آخر، كلما أمكن ذلك. 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 على الأجهزة التي تتضمّن أجهزة NFC فقط:<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>
الحصول على معلومات من النوايا
إذا بدأ نشاط معيّن لغرض NFC، يمكنك الحصول على معلومات حول علامة NFC الممسوحة ضوئيًا من الغرض. يمكن أن تحتوي الأهداف على البيانات الإضافية التالية استنادًا إلى العلامة التي تم مسحها ضوئيًا:
-
EXTRA_TAG
(سمة مطلوبة): عنصرTag
يمثّل العلامة التي تم مسحها ضوئيًا. EXTRA_NDEF_MESSAGES
(اختياري): مصفوفة من رسائل NDEF تم تحليلها من العلامة. هذه الإضافة إلزامية فيACTION_NDEF_DISCOVERED
النية.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 التي تكتبها إلى العلامة.
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
يمكنك إنشاء سجلّ NDEF بتنسيق TNF_EXTERNAL_TYPE
بالطُرق التالية:
باستخدام طريقة 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 أو عنوان URI فريدَين نسبيًا لتسهيل تمييز التطبيقات بينهما.
يوفّر 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")} ); )