يوضّح هذا المستند مهام NFC الأساسية التي يمكنك تنفيذها في Android. توضّح هذه الصفحة كيفية إرسال بيانات NFC وتلقّيها في شكل رسائل NDEF، كما تصف واجهات برمجة التطبيقات لإطار عمل Android التي تتيح هذه الميزات. للاطّلاع على مواضيع أكثر تقدّمًا، بما في ذلك مناقشة حول التعامل مع البيانات غير المتوافقة مع تنسيق NDEF، راجِع تقنية الاتصال القريب المدى المتقدّمة.
تتم معالجة قراءة بيانات NDEF من علامة NFC باستخدام نظام إرسال العلامات، الذي يحلّل علامات NFC التي تم اكتشافها، ويصنّف البيانات بشكل مناسب، ويبدأ تشغيل تطبيق مهتم بالبيانات المصنّفة. يمكن لأي تطبيق يريد معالجة علامة NFC تم فحصها تحديد فلتر أهداف وطلب معالجة البيانات.
نظام إرسال العلامات
تبحث أجهزة 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 إلى التطبيقات
عندما ينتهي نظام إرسال العلامات من إنشاء هدف يغلّف علامة NFC ومعلوماتها التعريفية، يرسل الهدف إلى تطبيق مهتمّ يفلتر الهدف. إذا كان بإمكان أكثر من تطبيق معالجة الغرض، سيتم عرض "أداة اختيار النشاط" ليتمكّن المستخدم من اختيار النشاط. يحدّد نظام إرسال العلامات ثلاث نوايا، وهي مدرَجة حسب الأولوية من الأعلى إلى الأدنى:
-
ACTION_NDEF_DISCOVERED: يتم استخدام هذا الغرض لبدء نشاط عند فحص علامة تحتوي على حمولة NDEF من نوع معروف. هذه هي نية الأولوية القصوى، ويحاول نظام إرسال العلامات بدء نشاط بهذه النية قبل أي نية أخرى، كلما أمكن ذلك.ملاحظة: بدءًا من Android 16، يؤدي فحص علامات NFC التي تخزّن روابط الويب (أي أنّ مخطط URI هو "http://" أو "https://") إلى تشغيل الغرض
ACTION_VIEWبدلاً من الغرضACTION_NDEF_DISCOVERED. بدءًا من Android 17، يؤدي فحص مثل هذا العلامة إلى ظهور إشعار "فتح الرابط"، ما يتطلّب تفاعلاً صريحًا من المستخدم لتفعيل الغرضACTION_VIEW. 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 من واجهة برمجة التطبيقات)، إذا كان التطبيق يستهدف الإصدار
Build.VERSION_CODES.BAKLAVAأو إصدارًا أحدث من حزمة تطوير البرامج (SDK)، يجب أن يكون النشاط محميًا بإذنandroid.permission.DISPATCH_NFC_MESSAGEكي يتم إرسال غرض NFC إليه. يضمن ذلك عدم إمكانية إرسال أي خدمات أخرى غير خدمة نظام 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
للفلترة حسب intents ACTION_NDEF_DISCOVERED، عليك تعريف intent filter مع نوع البيانات التي تريد الفلترة حسبها. يعرض المثال التالي فلترًا لطلبات 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 التي تخزّن روابط ويب (أي أنّ مخطّط URI هو "http://" أو "https://") إلى تشغيل الغرض ACTION_VIEW بدلاً من الغرض ACTION_NDEF_DISCOVERED. بدءًا من Android 17، يؤدي فحص مثل هذا العلامة إلى ظهور إشعار "فتح الرابط"، ما يتطلّب تفاعلاً صريحًا من المستخدم لتفعيل الغرض 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) تلقائيًا. بدءًا من Android 4.1 (المستوى 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، ومع ذلك، يوضّح مواصفات RTD الصادرة عن منتدى NFC
أنّه يجب حذف الجزء urn:nfc:ext: من اسم المورد الموحّد من سجلّ NDEF. لذا، كل ما عليك تقديمه هو النطاق (example.com في المثال) والنوع (externalType في المثال) مفصولَين بنقطتَين رأسيتَين.
عند إرسال TNF_EXTERNAL_TYPE، يحوّل نظام التشغيل Android معرّف الموارد الموحّد (URN) urn:nfc:ext:example.com:externalType
إلى معرّف موارد منتظم (URI) vnd.android.nfc://ext/example.com:externalType، وهو ما يعرّفه intent filter في المثال.
سجلات تطبيقات 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.