يوضّح هذا المستند مهام NFC الأساسية التي تنفّذها في Android. توضّح هذه الصفحة كيفية إرسال بيانات NFC وتلقّيها في شكل رسائل NDEF، كما تصف واجهات برمجة التطبيقات لإطار عمل Android التي تتيح هذه الميزات. للاطّلاع على مواضيع أكثر تقدّمًا، بما في ذلك مناقشة حول التعامل مع البيانات غير المتوافقة مع تنسيق تبادل بيانات NFC، راجِع تقنية NFC المتقدّمة.
تتم معالجة قراءة بيانات NDEF من علامة NFC باستخدام نظام إرسال العلامات، الذي يحلّل علامات NFC التي تم اكتشافها ويصنّف البيانات بشكل مناسب ويبدأ تطبيقًا مهتمًا بالبيانات المصنّفة. يمكن لأي تطبيق يريد معالجة علامة NFC تم فحصها تحديد intent filter وطلب معالجة البيانات.
نظام إرسال العلامات
تبحث أجهزة Android عادةً عن علامات NFC عندما تكون الشاشة غير مقفلة، ما لم يتم إيقاف NFC في قائمة "الإعدادات" بالجهاز. عندما يعثر جهاز يعمل بنظام التشغيل Android على علامة NFC، يكون السلوك المطلوب هو أن يعالج النشاط الأنسب الغرض بدون أن يسأل المستخدم عن التطبيق الذي يريد استخدامه. بما أنّ الأجهزة تفحص علامات NFC من مسافة قصيرة جدًا، من المحتمل أنّ مطالبة المستخدمين باختيار نشاط يدويًا ستجبرهم على إبعاد الجهاز عن العلامة وقطع الاتصال. عليك تطوير نشاطك للتعامل فقط مع علامات NFC التي يهتم بها نشاطك لمنع ظهور "أداة اختيار النشاط".
لمساعدتك في تحقيق هذا الهدف، يوفّر نظام Android نظامًا خاصًا لإرسال العلامات يحلّل علامات NFC التي تم فحصها ويحلّلها ويحاول تحديد التطبيقات التي تهتم بالبيانات التي تم فحصها. ويتم ذلك من خلال:
- تحليل علامة NFC وتحديد نوع MIME أو معرّف الموارد المنتظم (URI) الذي يحدّد حمولة البيانات في العلامة
- تغليف نوع MIME أو معرّف الموارد المنتظم (URI) والحِمل في هدف تم توضيح هاتين الخطوتين الأوليَين في مقالة كيفية ربط علامات NFC بأنواع MIME ومعرّفات الموارد المنتظمة (URI).
- يبدأ نشاطًا استنادًا إلى الغرض. يتم توضيح ذلك في مقالة كيفية إرسال علامات NFC إلى التطبيقات.
كيفية ربط علامات NFC بأنواع MIME ومعرّفات الموارد الموحّدة (URI)
قبل البدء في كتابة تطبيقات NFC، من المهم فهم الأنواع المختلفة لعلامات NFC، وكيفية تحليل نظام إرسال العلامات لعلامات NFC، والعمل الخاص الذي يقوم به نظام إرسال العلامات عند رصد رسالة NDEF. تتوفّر علامات NFC في مجموعة كبيرة من التقنيات، ويمكن أيضًا كتابة البيانات إليها بطرق مختلفة. يتوافق نظام التشغيل Android مع معيار NDEF الذي يحدّده منتدى NFC.
يتم تغليف بيانات NDEF داخل رسالة (NdefMessage) تحتوي على سجلّ واحد أو أكثر (NdefRecord). ويجب أن يكون كل سجلّ NDEF منسّقًا بشكل جيد وفقًا لمواصفات نوع السجلّ الذي تريد إنشاءه. يتيح نظام التشغيل Android أيضًا أنواعًا أخرى من العلامات التي لا تحتوي على بيانات NDEF، ويمكنك التعامل معها باستخدام الفئات في حزمة android.nfc.tech. لمزيد من المعلومات حول هذه التقنيات، اطّلِع على موضوع تقنية الاتصال القريب المدى المتقدّمة. يتطلّب العمل مع هذه الأنواع الأخرى من العلامات كتابة حزمة البروتوكول الخاصة بك للتواصل مع العلامات، لذا ننصح باستخدام NDEF عند الإمكان لتسهيل عملية التطوير وتوفير أقصى قدر من التوافق مع الأجهزة التي تعمل بنظام التشغيل Android.
ملاحظة: لتنزيل مواصفات NDEF الكاملة، انتقِل إلى موقع مواصفات NFC Forum ومستندات التطبيقات واطّلِع على إنشاء أنواع شائعة من سجلات 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 والنوع لمحاولة ربط نوع MIME أو معرّف موارد منتظم (URI) برسالة NDEF. في حال نجاح العملية، يتم تغليف هذه المعلومات داخل ACTION_NDEF_DISCOVERED intent مع حمولة البيانات الفعلية. ومع ذلك، هناك حالات لا يستطيع فيها نظام إرسال العلامات تحديد نوع البيانات استنادًا إلى سجلّ NDEF الأول. يحدث ذلك عندما يتعذّر ربط بيانات NDEF بنوع MIME أو معرّف URI، أو عندما لا تحتوي علامة NFC على بيانات NDEF في الأساس. في مثل هذه الحالات، يتم تضمين عنصر Tag يحتوي على معلومات حول تقنيات العلامة والحِمل النافع داخل هدف ACTION_TECH_DISCOVERED بدلاً من ذلك.
يوضّح الجدول 1 كيفية ربط نظام إرسال العلامات بحقلَي TNF والنوع بأنواع MIME أو معرّفات الموارد المنتظمة (URI). ويوضّح أيضًا أنواع NDEF التي لا يمكن ربطها بنوع MIME أو معرّف URI.
في هذه الحالات، يعود نظام إرسال العلامات إلى
ACTION_TECH_DISCOVERED.
على سبيل المثال، إذا صادف نظام إرسال العلامات سجلاً من النوع TNF_ABSOLUTE_URI، سيتم ربط حقل نوع الطول المتغير الخاص بهذا السجلّ بمعرّف موارد منتظم (URI). يغلّف نظام إرسال العلامات معرّف الموارد المنتظم (URI) هذا في حقل البيانات الخاص بغرض ACTION_NDEF_DISCOVERED مع معلومات أخرى عن العلامة، مثل الحمولة. من ناحية أخرى، إذا صادف سجلّاً من النوع TNF_UNKNOWN، سينشئ غرضًا يغلف تكنولوجيات العلامة بدلاً من ذلك.
الجدول 1. تنسيقات الملفات المتوافقة وعمليات الربط
| تنسيق الاسم (TNF) | الربط |
|---|---|
TNF_ABSOLUTE_URI |
عنوان URI استنادًا إلى حقل النوع |
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)، والذي تحدّده في حقل النوع اطّلِع على الجدول 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 |
عنوان URI استنادًا إلى تحليل الحمولة |
RTD_TEXT |
نوع MIME الخاص بـ text/plain. |
RTD_URI |
عنوان URI يستند إلى الحمولة. |
كيفية إرسال علامات NFC إلى التطبيقات
عندما ينتهي نظام إرسال العلامات من إنشاء intent يغلّف علامة NFC ومعلوماتها التي تكشف الهوية، يرسل الـ intent إلى تطبيق مهتم يفلتر الـ intent. إذا كان بإمكان أكثر من تطبيق معالجة الغرض، سيتم عرض "أداة اختيار النشاط" ليتمكّن المستخدم من اختيار النشاط. يحدّد نظام إرسال العلامات ثلاث نوايا، وهي مُدرَجة حسب ترتيب الأولوية من الأعلى إلى الأدنى:
-
ACTION_NDEF_DISCOVERED: يتم استخدام هذا الغرض لبدء نشاط عند فحص علامة تحتوي على حمولة NDEF من نوع معروف. هذه هي نية الأولوية القصوى، ويحاول نظام إرسال العلامات بدء نشاط بهذه النية قبل أي نية أخرى، كلما أمكن ذلك.ملاحظة: بدءًا من Android 16، سيؤدي فحص علامات NFC التي تخزّن روابط عناوين URL (أي أنّ مخطط URI هو "https://" أو "http://") إلى تشغيل الغرض
ACTION_VIEWبدلاً من الغرضACTION_NDEF_DISCOVERED. ACTION_TECH_DISCOVERED: إذا لم يتم تسجيل أي أنشطة للتعامل مع الغرضACTION_NDEF_DISCOVERED، يحاول نظام إرسال العلامات بدء تطبيق بهذا الغرض. يتم أيضًا بدء هذا الغرض مباشرةً (بدون بدءACTION_NDEF_DISCOVEREDأولاً) إذا كانت العلامة التي يتم فحصها تحتوي على بيانات NDEF لا يمكن ربطها بنوع MIME أو معرّف URI، أو إذا كانت العلامة لا تحتوي على بيانات NDEF ولكنها تستخدم تكنولوجيا علامات معروفة.-
ACTION_TAG_DISCOVERED: يتم بدء هذا الغرض في حال عدم معالجة أي أنشطة للغرضينACTION_NDEF_DISCOVEREDأوACTION_TECH_DISCOVERED.
في ما يلي الطريقة الأساسية التي يعمل بها نظام إرسال العلامات:
- حاوِل بدء نشاط باستخدام الغرض الذي أنشأه نظام إرسال العلامات
عند تحليل علامة NFC (إما
ACTION_NDEF_DISCOVEREDأوACTION_TECH_DISCOVERED). - إذا لم يكن هناك فلتر أنشطة لهذا الغرض، حاوِل بدء نشاط باستخدام الغرض التالي ذي الأولوية الأقل (إما
ACTION_TECH_DISCOVEREDأوACTION_TAG_DISCOVERED) إلى أن يفلتر أحد التطبيقات الغرض أو إلى أن يحاول نظام إرسال العلامات جميع الأغراض الممكنة. - إذا لم يتم فلترة أي تطبيقات لأي من الأهداف، لا تفعل شيئًا.
استخدِم رسائل NDEF وintent ACTION_NDEF_DISCOVERED كلما أمكن ذلك، لأنّها الأكثر تحديدًا من بين الثلاثة. يتيح لك هذا الغرض بدء تطبيقك في وقت أكثر ملاءمة من الغرضَين الآخرَين، ما يمنح المستخدم تجربة أفضل.
طلب إذن الوصول إلى NFC في ملف البيان Android
قبل أن تتمكّن من الوصول إلى أجهزة NFC والتعامل بشكل صحيح مع أغراض NFC، عليك تعريف العناصر التالية في ملف AndroidManifest.xml:
- عنصر NFC
<uses-permission>للوصول إلى أجهزة NFC:<uses-permission android:name="android.permission.NFC" />
- اعتبارًا من الإصدار 17 من نظام التشغيل Android (المستوى 37 من واجهة برمجة التطبيقات)، لكي يتم إرسال intent NFC إلى نشاط، إذا كان التطبيق يستهدف حزمة تطوير البرامج (SDK) >
Build.VERSION_CODES.BAKLAVA، يجب أن يكون محميًا بإذنandroid.permission.DISPATCH_NFC_MESSAGE. يضمن ذلك عدم إمكانية إرسال أي خدمة أخرى غير خدمة نظام NFC لطلبات إلى نشاطك. بالإضافة إلى ذلك، لن يرسل النظام نوايا NFC إلى التطبيقات التي تكون في حالة متوقفة (على سبيل المثال، إذا لم يسبق للمستخدم تشغيل التطبيق أو تم إيقافه بالقوة).<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> ... </activity>
- الحد الأدنى لإصدار حزمة تطوير البرامج (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:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter> </activity>
يقدّم المثال التالي فلترة لمعرّف URI بالتنسيق https://developer.android.com/index.html.
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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> </activity>
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 android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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>
لمزيد من المعلومات حول استخدام تقنيات العلامات والغرض ACTION_TECH_DISCOVERED، راجِع استخدام تقنيات العلامات المتوافقة في مستند "تقنية NFC المتقدّمة".
ACTION_TAG_DISCOVERED
ملاحظة: تم إيقاف ACTION_TAG_DISCOVERED نهائيًا بدءًا من Android 17 (مستوى واجهة برمجة التطبيقات 37). يُرجى استخدام ACTION_NDEF_DISCOVERED أو ACTION_TECH_DISCOVERED بدلاً من ذلك.
للفلترة حسب ACTION_TAG_DISCOVERED، استخدِم فلتر الأهداف التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter> </activity>
ACTION_VIEW
اعتبارًا من Android 16، سيؤدي مسح علامات NFC التي تخزّن روابط عناوين URL إلى تشغيل الغرض ACTION_VIEW. للفلترة حسب ACTION_VIEW،
يُرجى الرجوع إلى this. استخدِم Android app links لفتح تطبيقك لعنوان URL.
الحصول على معلومات من الأهداف
إذا بدأ نشاط بسبب عنصر intent خاص بتكنولوجيا NFC، يمكنك الحصول على معلومات حول علامة NFC التي تم مسحها ضوئيًا من عنصر intent. يمكن أن تحتوي الأهداف على الإضافات التالية استنادًا إلى العلامة التي تم فحصها ضوئيًا:
-
EXTRA_TAG(مطلوب): عنصرTagيمثّل العلامة الممسوحة ضوئيًا. -
EXTRA_NDEF_MESSAGES(اختياري): مصفوفة من رسائل NDEF تم تحليلها من العلامة. هذه البيانات الإضافية إلزامية في طلباتACTION_NDEF_DISCOVERED. -
EXTRA_ID(اختياري): المعرّف المنخفض المستوى للعلامة.
للحصول على هذه البيانات الإضافية، تحقَّق مما إذا كان نشاطك قد تم إطلاقه باستخدام إحدى نوايا NFC للتأكّد من أنّه تم إجراء مسح ضوئي لعلامة، ثم احصل على البيانات الإضافية من النية. يتحقّق المثال التالي من intent ACTION_NDEF_DISCOVERED ويحصل على رسائل NDEF من intent إضافي.
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. بدءًا من الإصدار 4.0 من نظام التشغيل Android (المستوى 14 من واجهة برمجة التطبيقات)، تتوفّر الطريقة
createUri() لمساعدتك في إنشاء
سجلّات URI تلقائيًا. بدءًا من الإصدار 4.1 من نظام التشغيل Android (المستوى 16 من واجهة برمجة التطبيقات)، يتوفّر النوعان createExternal() وcreateMime() لمساعدتك في إنشاء سجلات NDEF من نوع MIME وخارجية. استخدِم طرق المساعدة هذه كلما أمكن لتجنُّب الأخطاء عند إنشاء سجلات NDEF يدويًا.
يوضّح هذا القسم أيضًا كيفية إنشاء intent filter ذي الصلة بالسجلّ. يجب أن تكون كل أمثلة سجلات NDEF هذه في سجل NDEF الأول من رسالة NDEF التي تكتبها على علامة.
TNF_ABSOLUTE_URI
ملاحظة: ننصحك باستخدام النوع RTD_URI بدلاً من TNF_ABSOLUTE_URI لأنّه أكثر فعالية.
يمكنك إنشاء سجلّ TNF_ABSOLUTE_URI NDEF بالطريقة التالية
:
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 السابق على النحو التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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> </activity>
TNF_MIME_MEDIA
يمكنك إنشاء TNF_MIME_MEDIA سجلّ NDEF بالطرق التالية:
باستخدام طريقة 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 السابق على النحو التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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> </activity>
TNF_WELL_KNOWN مع RTD_TEXT
يمكنك إنشاء سجلّ TNF_WELL_KNOWN NDEF بالطريقة التالية:
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 السابق على النحو التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity>
TNF_WELL_KNOWN مع RTD_URI
يمكنك إنشاء TNF_WELL_KNOWN سجلّ NDEF بالطرق التالية:
باستخدام طريقة 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 السابق على النحو التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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> </activity>
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 السابق على النحو التالي:
<activity android:name=".MyActivity" android:exported="true" android:permission="android.permission.DISPATCH_NFC_MESSAGE"> <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> </activity>
استخدِم TNF_EXTERNAL_TYPE لعمليات نشر علامات NFC الأكثر عمومية من أجل توفير دعم أفضل لكل من الأجهزة التي تعمل بنظام التشغيل Android والأجهزة التي لا تعمل به.
ملاحظة: تتضمّن معرّفات الموارد الموحّدة (URN) الخاصة بـ TNF_EXTERNAL_TYPE تنسيقًا أساسيًا هو:
urn:nfc:ext:example.com:externalType، إلا أنّ مواصفات تنسيق بيانات سجلات NFC Forum
توضّح أنّه يجب حذف جزء urn:nfc:ext: من معرّف الموارد الموحّد من
سجل NDEF. كل ما عليك تقديمه هو النطاق (example.com في المثال) والنوع (externalType في المثال) مفصولَين بنقطتَين رأسيتَين.
عند إرسال TNF_EXTERNAL_TYPE، يحوّل نظام التشغيل Android معرّف الموارد الموحّد urn:nfc:ext:example.com:externalType
إلى معرّف الموارد المنتظم 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، يرسل نظام إرسال العلامات الطلب بالطريقة التالية:
- حاوِل بدء نشاط باستخدام intent filter كالمعتاد. إذا كان النشاط الذي يتطابق مع الغرض يتطابق أيضًا مع AAR، ابدأ النشاط.
- إذا كان النشاط الذي يفلتر الغرض لا يتطابق مع AAR، أو إذا كان بإمكان أنشطة متعددة التعامل مع الغرض، أو إذا لم يتعامل أي نشاط مع الغرض، ابدأ التطبيق المحدّد بواسطة AAR.
- إذا لم يتمكّن أي تطبيق من البدء باستخدام AAR، انتقِل إلى Google Play لتنزيل التطبيق استنادًا إلى AAR.
ملاحظة: يمكنك إلغاء معالجة AAR ونظام إرسال الأهداف باستخدام نظام الإرسال في المقدّمة، ما يتيح لنشاط في المقدّمة الحصول على الأولوية عند اكتشاف علامة NFC. باستخدام هذه الطريقة، يجب أن يكون النشاط في المقدّمة لتجاوز طلبات AAR ونظام إرسال الأهداف.
إذا كنت لا تزال تريد فلترة العلامات التي تم فحصها والتي لا تحتوي على سجلّ AAR، يمكنك تعريف فلاتر الأهداف كالمعتاد. ويكون ذلك مفيدًا إذا كان تطبيقك مهتمًا بعلامات أخرى لا تحتوي على سجلّ AAR. على سبيل المثال، قد تريد ضمان أنّ تطبيقك يتعامل مع العلامات الخاصة التي تنشرها بالإضافة إلى العلامات العامة التي تنشرها الجهات الخارجية. يُرجى العِلم أنّ سجلات AAR مخصّصة لأجهزة Android 4.0 أو الإصدارات الأحدث، لذا عند نشر العلامات، من الأفضل استخدام مجموعة من سجلات AAR وأنواع MIME/معرّفات URI لتوفير التوافق مع أكبر مجموعة من الأجهزة. بالإضافة إلى ذلك، عند نشر علامات NFC، فكِّر في الطريقة التي تريد بها كتابة علامات NFC لتوفير الدعم لأكبر عدد من الأجهزة (الأجهزة التي تعمل بنظام التشغيل Android والأجهزة الأخرى). يمكنك إجراء ذلك من خلال تحديد نوع MIME أو عنوان URI فريد نسبيًا لتسهيل التمييز على التطبيقات.
يوفّر نظام التشغيل Android واجهة برمجة تطبيقات بسيطة لإنشاء ملف AAR,
createApplicationRecord(). كل ما عليك فعله هو تضمين ملف AAR في أي مكان في NdefMessage. لا ننصحك باستخدام السجلّ الأول من NdefMessage، إلا إذا كان سجلّ AAR هو السجلّ الوحيد في NdefMessage. ويرجع ذلك إلى أنّ نظام Android يتحقّق من السجلّ الأول في NdefMessage لتحديد نوع MIME أو معرّف الموارد المنتظم (URI) الخاص بالعلامة، والذي يُستخدَم لإنشاء هدف لتتمكّن التطبيقات من فلترته. يوضّح الرمز التالي كيفية إنشاء ملف 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 ضوئيًا
اعتبارًا من Android 16، يتم إرسال إشعار إلى المستخدمين عندما يتلقّى التطبيق أول غرض NFC لفحص علامات NFC. يُتاح للمستخدم خيار منع التطبيق من البحث عن علامات NFC مرة أخرى في الإشعار.
- يمكن للتطبيقات التحقّق مما إذا كان المستخدم قد سمح لها بفحص علامات NFC باستخدام
NfcAdapter.isTagIntentAllowed(). - يمكن للتطبيقات أن تطلب من المستخدم السماح بمسح علامات NFC ضوئيًا مرة أخرى عن طريق إرسال الغرض
ACTION_CHANGE_TAG_INTENT_PREFERENCE.
ملاحظة: يمكن الوصول إلى قائمة التطبيقات المسموح لها بمسح علامات NFC ضوئيًا ضمن Settings > Apps > Special app access > Launch via NFC.