أساسيات تقنية NFC

يصف هذا المستند مهام NFC الأساسية التي تؤديها في نظام Android. وهو يشرح كيفية إرسال بيانات NFC واستلامها على شكل رسائل NDEF ويصف واجهات برمجة تطبيقات إطار عمل Android التي تتوافق مع هذه الميزات. للاطّلاع على مواضيع أكثر تقدمًا، بما في ذلك مناقشة استخدام البيانات غير التابعة لـ NDEF، راجِع تقنية NFC المتقدّمة.

هناك حالتا استخدام رئيسيتان عند التعامل مع بيانات NDEF وAndroid:

  • قراءة بيانات NDEF من علامة NFC
  • إرسال رسائل NDEF من جهاز إلى آخر باستخدام Android BeamTM

تتم معالجة قراءة بيانات NDEF من علامة NFC باستخدام نظام إرسال العلامات الذي يحلّل علامات NFC التي تم اكتشافها ويصنِّف البيانات بشكل مناسب، ويشغِّل تطبيقًا مهتمًا بالبيانات المصنَّفة. ويمكن للتطبيق الذي يريد معالجة علامة NFC التي تم فحصها الإعلان عن فلتر أهداف وطلب معالجة البيانات.

تتيح ميزة Android BeamTM للجهاز إرسال رسالة NDEF إلى جهاز آخر من خلال التلامس بين الجهازين معًا. يوفّر هذا التفاعل طريقة أسهل لإرسال البيانات مقارنةً بالتقنيات اللاسلكية الأخرى مثل البلوتوث، لأنّه باستخدام تقنية NFC، لا حاجة إلى اكتشاف الجهاز أو إقرانه يدويًا. يبدأ الاتصال تلقائيًا عندما يظهر جهازان في النطاق. يتوفر تطبيق "شعاع Android" من خلال مجموعة من واجهات برمجة تطبيقات تقنية NFC، لذلك يمكن لأي تطبيق نقل المعلومات بين الأجهزة. على سبيل المثال، تستخدم تطبيقات جهات الاتصال والمتصفح وYouTube شعاع Android لمشاركة جهات الاتصال وصفحات الويب ومقاطع الفيديو مع الأجهزة الأخرى.

نظام إرسال العلامات

تبحث عادةً الأجهزة التي تعمل بنظام التشغيل Android عن علامات NFC عندما يتم فتح قفل الشاشة، ما لم تكن هذه الميزة غير مفعّلة في قائمة إعدادات الجهاز. عندما يرصد جهاز يعمل بنظام التشغيل Android علامة NFC، يكون السلوك المطلوب هو ضبط الهدف الأنسب من خلال النشاط بدون سؤال المستخدم عن التطبيق الذي يجب استخدامه. بما أنّ الأجهزة تفحص علامات NFC على نطاق قصير جدًا، من المحتمل أن يؤدي تكليف المستخدمين باختيار نشاط يدويًا إلى إجبارهم على إبعاد الجهاز عن العلامة وقطع الاتصال. يجب تطوير نشاطك للتعامل مع علامات NFC التي يهتم بها نشاطك فقط لمنع ظهور "أداة اختيار النشاط".

لمساعدتك في تحقيق هذا الهدف، يوفّر Android نظامًا خاصًا لإرسال العلامات يحلل علامات NFC الممسوحة ضوئيًا ويحلّلها ويحاول تحديد موقع التطبيقات المهتمة بالبيانات التي تم فحصها. يتم ذلك عن طريق:

  1. تحليل علامة NFC وتحديد نوع MIME أو معرّف الموارد المنتظم (URI) الذي يحدّد حمولة البيانات في العلامة.
  2. تغليف نوع MIME أو عنوان URI والحمولة في الغرض. ويتم توضيح أول خطوتَين في مقالة كيفية ربط علامات NFC بأنواع MIME ومعرّفات الموارد المنتظمة (URI).
  3. بدء نشاط بناءً على الغرض. ويمكنك الاطّلاع على مزيد من المعلومات في مقالة كيفية إرسال علامات NFC إلى التطبيقات.

كيفية ربط علامات NFC بأنواع MIME ومعرّفات الموارد المنتظمة (URI)

قبل البدء في كتابة تطبيقات NFC، من المهم فهم الأنواع المختلفة من علامات NFC وكيفية تحليل نظام إرسال العلامات لعلامات NFC والعمل الخاص الذي يقوم به نظام إرسال العلامات عند اكتشاف رسالة NDEF. تتوفّر علامات NFC في مجموعة واسعة من التقنيات ويمكن أن تحتوي أيضًا على بيانات مكتوبة عليها بعدة طرق مختلفة. وتجدر الإشارة إلى أنّ Android بأكبر قدر من التوافق مع معيار NDEF، المحدّد في منتدى NFC.

يتم تغليف بيانات NDEF داخل رسالة (NdefMessage) تشتمل على سجل واحد أو أكثر (NdefRecord). يجب أن يكون كل سجل NDEF بتنسيق جيد وفقًا لمواصفات نوع السجل الذي تريد إنشاءه. ويتيح Android أيضًا أنواعًا أخرى من العلامات التي لا تحتوي على بيانات NDEF، التي يمكنك التعامل معها باستخدام الفئات المتوفّرة في حزمة android.nfc.tech. للاطّلاع على مزيد من المعلومات حول هذه التكنولوجيات، يمكنك مراجعة موضوع تقنية الاتصال القصير المدى (NFC) المتقدمة. ينطوي العمل باستخدام هذه الأنواع الأخرى من العلامات على كتابة حزمة البروتوكول الخاصة بك للتواصل مع العلامات، لذا ننصح باستخدام NDEF عندما يكون ذلك ممكنًا لتسهيل التطوير والحصول على أقصى دعم ممكن للأجهزة التي تعمل بنظام التشغيل Android.

ملاحظة: لتنزيل مواصفات NDEF الكاملة، يُرجى الانتقال إلى الموقع الإلكتروني مواصفات منتدى NFC ومستندات الطلب والاطّلاع على إنشاء أنواع شائعة من سجلّات NDEF للحصول على أمثلة حول كيفية إنشاء سجلّات NDEF.

بعد أن توفّرت لديك الآن بعض المعلومات الأساسية عن علامات NFC، تشرح الأقسام التالية بمزيد من التفصيل كيفية تعامل Android مع علامات NDEF المنسّقة. عندما يفحص جهاز يعمل بنظام التشغيل Android علامة NFC تحتوي على بيانات بتنسيق NDEF، فإنه يحلل الرسالة ويحاول تحديد نوع MIME للبيانات أو معرف الموارد المنتظم (URI) للبيانات. لإجراء ذلك، يقرأ النظام أول NdefRecord ضمن NdefMessage لتحديد كيفية تفسير رسالة NDEF بأكملها (يمكن أن تحتوي رسالة NDEF على سجلات NDEF متعددة). في رسالة NDEF بتنسيق جيد، يحتوي أول NdefRecord على الحقول التالية:

3 بت TNF (تنسيق اسم النوع)
تشير هذه العلامة إلى كيفية تفسير حقل نوع متغير الطول. يتم وصف القيم الصالحة في الجدول 1.
نوع متغيّر الطول
يصف هذا الحقل نوع السجلّ. في حال استخدام السمة TNF_WELL_KNOWN، استخدِم هذا الحقل لتحديد تعريف نوع السجلّ (RTD). يتم توضيح قيم "المراسلة النصية في الوقت الفعلي" الصالحة في الجدول 2.
رقم تعريف الطول المتغيّر
معرّف فريد للسجلّ لا يتمّ استخدام هذا الحقل كثيرًا، ولكن إذا كنت بحاجة إلى تحديد علامة بشكلٍ فريد، يمكنك إنشاء معرّف لها.
حمولة متغيرة الطول
حمولة البيانات الفعلية التي تريد قراءتها أو كتابتها يمكن أن تحتوي رسالة NDEF على العديد من سجلات NDEF، لذلك لا تفترض أن الحمولة الكاملة في سجل NDEF الأول لرسالة NDEF.

يستخدم نظام إرسال العلامة حقلَي TNF وtype لمحاولة ربط نوع MIME أو معرّف موارد منتظم (URI) لرسالة NDEF. في حال نجاح هذه العملية، فإنها تتضمّن تلك المعلومات داخل الغرض ACTION_NDEF_DISCOVERED مع الحمولة الفعلية. ومع ذلك، هناك حالات يتعذّر فيها على نظام إرسال العلامة تحديد نوع البيانات استنادًا إلى سجلّ NDEF الأول. ويحدث ذلك عندما يتعذّر ربط بيانات NDEF بنوع MIME أو معرّف موارد منتظم (URI)، أو عندما لا تحتوي علامة NFC على بيانات NDEF للبدء بها. وفي هذه الحالات، يتم تضمين كائن Tag الذي يحتوي على معلومات حول تقنيات العلامة والحمولة في هدف ACTION_TECH_DISCOVERED بدلاً من ذلك.

يوضّح الجدول 1 كيفية ربط نظام إرسال العلامة لحقول TNF وحقول الأنواع إلى أنواع MIME أو معرّفات الموارد المنتظمة (URI). كما يصف أيضًا ملفات TNF التي لا يمكن ربطها بنوع MIME أو معرّف الموارد المنتظم (URI). وفي هذه الحالات، يعود نظام إرسال العلامات إلى ACTION_TECH_DISCOVERED.

على سبيل المثال، إذا كان نظام إرسال العلامة يصادف سجلاً من النوع TNF_ABSOLUTE_URI، يتم ربط حقل النوع المتغيّر للسجلّ في معرّف الموارد المنتظم (URI). يتضمّن نظام إرسال العلامة معرّف الموارد المنتظم (URI) هذا في حقل بيانات الغرض ACTION_NDEF_DISCOVERED إلى جانب معلومات أخرى حول العلامة، مثل الحمولة. من ناحية أخرى، إذا صادفت سجلّاً من النوع TNF_UNKNOWN، ستنشئ غرضًا يتضمّن تقنيات العلامة بدلاً من ذلك.

الجدول 1. وحدات TNF المتوافقة وعمليات ربطها

كتابة تنسيق الاسم (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 للحصول على مزيد من المعلومات حول جهات الاتصال في الوقت الفعلي (RTD) المتاحة وعمليات الربط الخاصة بها.

الجدول 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 ومعلوماتها التعريفية، يرسل النظام الغرض إلى التطبيق المعنيّ الذي يجري الفلترة حسب الغرض. وإذا كان بإمكان أكثر من تطبيق واحد معالجة الغرض، سيتم عرض "أداة اختيار النشاط" ليتمكّن المستخدم من اختيار النشاط. يحدد نظام إرسال العلامات ثلاثة أغراض يتم إدراجها بالترتيب من أعلى إلى أدنى أولوية:

  1. ACTION_NDEF_DISCOVERED: يُستخدَم هذا الغرض لبدء نشاط عندما يتم فحص علامة تحتوي على حمولة بيانات NDEF وتكون من نوع معروف. هذه هي النية ذات الأولوية القصوى، ويحاول نظام إرسال العلامات بدء نشاط بهذه النية قبل أي نية أخرى، كلما أمكن ذلك.
  2. ACTION_TECH_DISCOVERED: في حال عدم تسجيل أي أنشطة لمعالجة هدف ACTION_NDEF_DISCOVERED، يحاول نظام إرسال العلامات تشغيل تطبيق بهذا الغرض. تبدأ هذه النية أيضًا (بدون بدء ACTION_NDEF_DISCOVERED أولاً) إذا كانت العلامة التي يتم مسحها ضوئيًا تحتوي على بيانات NDEF لا يمكن ربطها بنوع MIME أو معرّف موارد منتظم (URI)، أو إذا كانت العلامة لا تحتوي على بيانات NDEF ولكنها تشكّل تكنولوجيا علامة معروفة.
  3. ACTION_TAG_DISCOVERED: يبدأ هذا الغرض إذا لم تتناول أي أنشطة الهدفَين ACTION_NDEF_DISCOVERED أو ACTION_TECH_DISCOVERED.

في ما يلي الطريقة الأساسية التي يعمل بها نظام إرسال العلامات:

  1. حاوِل بدء نشاط بالقصد الذي أنشأه نظام إرسال العلامات عند تحليل علامة NFC (إما ACTION_NDEF_DISCOVERED أو ACTION_TECH_DISCOVERED).
  2. في حال عدم فلترة أي أنشطة لهذا الغرض، جرِّب بدء نشاط يتضمّن الغرض الأدنى التالي ذي الأولوية (إما ACTION_TECH_DISCOVERED أو ACTION_TAG_DISCOVERED) إلى أن يفلتر أحد التطبيقات الغرض أو إلى أن يجرّب نظام إرسال العلامة جميع الأغراض الممكنة.
  3. وإذا لم تتم فلترة أي تطبيق لأي من الأغراض، لا تتخذ أي إجراء.
الشكل 1. نظام إرسال العلامات

استخدِم قدر الإمكان رسائل NDEF وهدف ACTION_NDEF_DISCOVERED، لأنّه الأكثر تحديدًا من بين الثلاثة. يسمح لك هذا الغرض ببدء طلبك في وقت مناسب أكثر من الهدفَين الآخرَين، ما يمنح المستخدم تجربة أفضل.

طلب الوصول إلى NFC في بيان Android

قبل أن تتمكن من الوصول إلى جهاز NFC على جهازك والتعامل مع أهداف NFC بشكل صحيح، يُرجى الإفصاح عن العناصر التالية في ملف AndroidManifest.xml:

  • عنصر <uses-permission> NFC للوصول إلى جهاز NFC:
    <uses-permission android:name="android.permission.NFC" />
    
  • تمثّل هذه السمة الحد الأدنى لإصدار حزمة تطوير البرامج (SDK) الذي يمكن أن يتوافق مع تطبيقك. يتيح المستوى 9 من واجهة برمجة التطبيقات الإرسال المحدود للعلامات من خلال ACTION_TAG_DISCOVERED فقط، ولا يمنح إمكانية الوصول إلى رسائل NDEF إلا من خلال عنصر EXTRA_NDEF_MESSAGES الإضافي. ولا يمكن الوصول إلى خصائص العلامات الأخرى أو عمليات الإدخال والإخراج. يشمل المستوى 10 من واجهة برمجة التطبيقات دعمًا شاملاً للقارئ/الكُتب، بالإضافة إلى إرسال رموز NDEF في المقدّمة، كما أنّ المستوى 14 من واجهة برمجة التطبيقات يوفّر طريقة أسهل لإرسال رسائل NDEF إلى الأجهزة الأخرى باستخدام ميزة "شعاع Android" وطرقًا ملائمة إضافية لإنشاء سجلات 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 تريد التعامل معها، يمكن للتطبيق الفلترة بحثًا عن هدف واحد أو اثنتين أو الثلاثة جميعها في بيان 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>

في ما يلي مثال على فلاتر معرّف الموارد المنتظم (URI) بالتنسيق 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>

تم رصد إجراء_TECH_DISCOVERED

إذا تمت فلترة نشاطك لغرض ACTION_TECH_DISCOVERED، عليك إنشاء ملف موارد XML يحدد التقنيات التي يدعمها نشاطك ضمن مجموعة tech-list. ويُعدّ نشاطك مطابقًا إذا كانت مجموعة tech-list هي مجموعة فرعية من التكنولوجيات المتوافقة مع العلامة، والتي يمكنك الحصول عليها عن طريق طلب getTechList().

على سبيل المثال، إذا كانت العلامة التي يتم مسحها متوافقة مع Mifare Classic و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 وNdefA، أو التي يمكن أن تتوافق مع تقنيات 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>

لمزيد من المعلومات عن العمل باستخدام تقنيات العلامات وهدف ACTION_TECH_DISCOVERED، يُرجى الاطّلاع على العمل باستخدام تقنيات العلامات المتوافقة في مستند "تقنية الاتصال القصير المدى (NFC) المتقدّمة".

تم اكتشاف ACTION_TAG_ID

لفلترة ACTION_TAG_DISCOVERED، استخدِم فلتر الأهداف التالي:

<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

الحصول على معلومات من الأغراض

إذا بدأ النشاط بسبب هدف NFC، يمكنك الحصول على معلومات عن علامة NFC التي تم مسحها ضوئيًا من النية. يمكن أن تحتوي ملفات Intent على العناصر الإضافية التالية بناءً على العلامة التي تم فحصها:

  • 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. بدءًا من Android 4.0 (المستوى 14 لواجهة برمجة التطبيقات)، تتوفر طريقة createUri() لمساعدتك في إنشاء سجلات معرف الموارد المنتظم (URI) تلقائيًا. بدءًا من Android 4.1 (المستوى 16 لواجهة برمجة التطبيقات)، يتوفّر createExternal() وcreateMime() لمساعدتك في إنشاء سجلّات MIME والنوع الخارجي NDEF. استخدِم الأساليب المساعدة هذه كلما أمكن ذلك لتجنُّب الأخطاء عند إنشاء سجلات NDEF يدويًا.

ويصف هذا القسم أيضًا كيفية إنشاء فلتر النية المقابل للسجل. يجب أن تكون جميع أمثلة سجل NDEF هذه في سجل NDEF الأول لرسالة NDEF التي تكتبها في علامة أو شعاع.

معرّف الموارد المنتظم (URI) 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" إلى أنّه يجب حذف الجزء 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 4.0 (المستوى 14 لواجهة برمجة التطبيقات)، يساعد "سجلّ تطبيقات Android" في التأكّد من بدء تشغيل تطبيقك عندما يتم مسح علامة NFC ضوئيًا. يحتوي AAR على اسم حزمة تطبيق مضمّن داخل سجل NDEF. يمكنك إضافة سجل AAR إلى أي سجلّ NDEF لرسالة NDEF، لأن Android يبحث في رسالة NDEF بأكملها عن معرّفات AAR. وإذا عثر على AAR، فإنه يشغِّل التطبيق بناءً على اسم الحزمة داخل AAR. إذا لم يكن التطبيق موجودًا على الجهاز، فسيتم تشغيل Google Play لتنزيل التطبيق.

تكون الاقتراحات المطبّقة تلقائيًا مفيدة إذا كنت تريد منع التطبيقات الأخرى من الفلترة حسب الغرض نفسه وربما التعامل مع علامات معيّنة نشرتها. تتوفّر الاقتراحات المطبّقة تلقائيًا على مستوى التطبيق فقط، بسبب قيد اسم الحزمة، وليس على مستوى النشاط كما هو الحال مع فلترة النية. إذا كنت تريد معالجة هدف على مستوى النشاط، استخدِم فلاتر الأهداف.

إذا كانت إحدى العلامات تحتوي على AAR، يرسل نظام إرسال العلامات بالطريقة التالية:

  1. حاوِل بدء نشاط باستخدام فلتر أهداف كالمعتاد. إذا كان النشاط الذي يتطابق مع الغرض أيضًا يتطابق مع AAR، ابدأ النشاط.
  2. إذا كان النشاط الذي يعمل على فلترة الغرض لا يتطابق مع الاقتراحات المطبّقة تلقائيًا، أو إذا كان بإمكان أنشطة متعدّدة معالجة الغرض، أو إذا لم يقم "النشاط" بمعالجة الهدف، شغِّل التطبيق الذي حدّدته هذه الميزة.
  3. إذا تعذّر على أي تطبيق بدء استخدام AAR، انتقِل إلى Google Play لتنزيل التطبيق المستند إلى 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")}
        );
)

إرسال رسائل NDEF إلى أجهزة أخرى

يتيح شعاع Android إمكانية تبادل البيانات بسهولة بين جهازين يعملان بنظام التشغيل Android. ويجب أن يكون التطبيق الذي يريد إرسال البيانات إلى جهاز آخر في المقدّمة، كما يجب ألّا يكون الجهاز الذي يستقبل البيانات مغلقًا. عندما يقترب جهاز الإرسال من جهاز استقبال بدرجة كافية، يعرض الجهاز إرسال واجهة المستخدم "اللمس باللمس". ويمكن للمستخدم بعد ذلك اختيار ما إذا كنت تريد إرسال الرسالة إلى الجهاز المستلم أم لا.

ملاحظة: كان إرسال NDEF في المقدمة متاحًا على المستوى 10 من واجهة برمجة التطبيقات، والذي يوفّر وظائف مشابهة لـ Android Beam. تم إيقاف واجهات برمجة التطبيقات هذه منذ ذلك الحين، ولكنها متاحة لدعم الأجهزة القديمة. يُرجى الاطّلاع على enableForegroundNdefPush() للحصول على المزيد من المعلومات.

يمكنك تمكين شعاع Android لتطبيقك من خلال استدعاء إحدى الطريقتين التاليتين:

  • setNdefPushMessage(): يقبل NdefMessage لضبط كرسالة لإرسالها. تعمل هذه الميزة على إرسال الرسالة تلقائيًا عندما يكون جهازان قريبَين بدرجة كافية
  • setNdefPushMessageCallback(): تقبل معاودة الاتصال التي تحتوي على createNdefMessage() التي يتم استدعائها عندما يكون الجهاز في النطاق المطلوب إرسال البيانات إليه. تتيح لك معاودة الاتصال إنشاء رسالة NDEF عند الضرورة فقط.

لا يمكن لأي نشاط دفع أكثر من رسالة NDEF واحدة في كل مرة، لذا تكون الأولوية للدالة setNdefPushMessageCallback() على setNdefPushMessage() في حال ضبط كلتا القيمتين. لاستخدام ميزة شعاع Android، يجب استيفاء الإرشادات العامة التالية:

  • يجب أن يكون النشاط الذي يرسل البيانات في المقدمة. يجب فتح قفل شاشتهما في كلا الجهازين
  • يجب تغليف البيانات التي ترسلها في كائن NdefMessage.
  • يجب أن يكون جهاز NFC الذي يتلقى بيانات الإرسال متوافقًا مع بروتوكول NDEF للدفع com.android.npp أو بروتوكول SNEP (البروتوكول البسيط لتبادل NDEF) الخاص بمنتدى NFC. يجب استخدام بروتوكول com.android.npp للأجهزة التي تعمل بالمستوى 9 من واجهة برمجة التطبيقات (Android 2.3) وحتى المستوى 13 من واجهة برمجة التطبيقات (Android 3.2). يجب توفير كل من com.android.npp وSNEP في المستوى 14 من واجهة برمجة التطبيقات (الإصدار 4.0 من نظام التشغيل Android) والإصدارات الأحدث.

ملاحظة: إذا كان نشاطك يفعّل ميزة "شعاع Android" وكان في المقدّمة، سيتم إيقاف نظام إرسال الأهداف العادية. ومع ذلك، إذا كان نشاطك يتيح أيضًا الإرسال إلى المقدّمة، سيظل بإمكانه فحص العلامات التي تتطابق مع فلاتر الأهداف التي تم ضبطها في عملية الإرسال التي تعمل في المقدّمة.

لتمكين شعاع Android:

  1. أنشِئ NdefMessage يحتوي على عناصر NdefRecord التي تريد فرضها على الجهاز الآخر.
  2. يمكنك استدعاء "setNdefPushMessage()" باستخدام NdefMessage أو الطلب "setNdefPushMessageCallback" مع تمرير عنصر NfcAdapter.CreateNdefMessageCallback في طريقة onCreate() من نشاطك. تتطلب هذه الطرق نشاطًا واحدًا على الأقل تريد تفعيله باستخدام ميزة شعاع Android، بالإضافة إلى قائمة اختيارية بالأنشطة الأخرى المطلوب تنشيطها.

    بشكل عام، أنت تستخدم عادةً setNdefPushMessage() إذا كان نشاطك يحتاج فقط إلى إرسال رسالة NDEF نفسها طوال الوقت، عندما يكون هناك جهازان في النطاق للاتصال. يمكنك استخدام setNdefPushMessageCallback عندما يهتم تطبيقك بالسياق الحالي للتطبيق ويريد إرسال رسالة NDEF بناءً على ما يفعله المستخدم في تطبيقك.

يوضح النموذج التالي كيفية استدعاء نشاط بسيط NfcAdapter.CreateNdefMessageCallback في طريقة onCreate() للنشاط (راجع AndroidBeamDemo للحصول على النموذج الكامل). يتضمّن هذا المثال أيضًا طرقًا لمساعدتك في إنشاء سجلّ MIME:

Kotlin

package com.example.android.beam

import android.app.Activity
import android.content.Intent
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.nfc.NfcAdapter.CreateNdefMessageCallback
import android.nfc.NfcEvent
import android.os.Bundle
import android.os.Parcelable
import android.widget.TextView
import android.widget.Toast
import java.nio.charset.Charset

class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback {
    
    private var nfcAdapter: NfcAdapter? = null
    private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
        textView = findViewById(R.id.textView)
        // Check for available NFC Adapter
        nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        if (nfcAdapter == null) {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show()
            finish()
            return
        }
        // Register callback
        nfcAdapter?.setNdefPushMessageCallback(this, this)
    }

    override fun createNdefMessage(event: NfcEvent): NdefMessage {
        val text = "Beam me up, Android!\n\n" +
                "Beam Time: " + System.currentTimeMillis()
        return NdefMessage(
                arrayOf(
                        createMime("application/vnd.com.example.android.beam", text.toByteArray())
                )
                /**
                 * The Android Application Record (AAR) is commented out. When a device
                 * receives a push with an AAR in it, the application specified in the AAR
                 * is guaranteed to run. The AAR overrides the tag dispatch system.
                 * You can add it back in to guarantee that this
                 * activity starts when receiving a beamed message. For now, this code
                 * uses the tag dispatch system.
                 *///,NdefRecord.createApplicationRecord("com.example.android.beam")
        )
    }

    override fun onResume() {
        super.onResume()
        // Check to see that the Activity started due to an Android Beam
        if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) {
            processIntent(intent)
        }
    }

    override fun onNewIntent(intent: Intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent)
    }

    /**
     * Parses the NDEF Message from the intent and prints to the TextView
     */
    private fun processIntent(intent: Intent) {
        textView = findViewById(R.id.textView)
        // only one message sent during the beam
        intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs ->
            (rawMsgs[0] as NdefMessage).apply {
                // record 0 contains the MIME type, record 1 is the AAR, if present
                textView.text = String(records[0].payload)
            }
        }
    }
}

Java

package com.example.android.beam;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;


public class Beam extends Activity implements CreateNdefMessageCallback {
    NfcAdapter nfcAdapter;
    TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView = (TextView) findViewById(R.id.textView);
        // Check for available NFC Adapter
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (nfcAdapter == null) {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        // Register callback
        nfcAdapter.setNdefPushMessageCallback(this, this);
    }

    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        String text = ("Beam me up, Android!\n\n" +
                "Beam Time: " + System.currentTimeMillis());
        NdefMessage msg = new NdefMessage(
                new NdefRecord[] { createMime(
                        "application/vnd.com.example.android.beam", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          //,NdefRecord.createApplicationRecord("com.example.android.beam")
        });
        return msg;
    }

    @Override
    public void onResume() {
        super.onResume();
        // Check to see that the Activity started due to an Android Beam
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
            processIntent(getIntent());
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent);
    }

    /**
     * Parses the NDEF Message from the intent and prints to the TextView
     */
    void processIntent(Intent intent) {
        textView = (TextView) findViewById(R.id.textView);
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
                NfcAdapter.EXTRA_NDEF_MESSAGES);
        // only one message sent during the beam
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        // record 0 contains the MIME type, record 1 is the AAR, if present
        textView.setText(new String(msg.getRecords()[0].getPayload()));
    }
}

تجدر الإشارة إلى أن هذا الرمز يعلق AAR، والذي يمكنك إزالته. في حال تفعيل ميزة AAR، سيتلقّى التطبيق المحدد في هذه الميزة رسالة شعاع Android دائمًا. في حال عدم توفّر التطبيق، يبدأ Google Play بتنزيل التطبيق. ولذلك، لا يكون فلتر الأهداف التالي ضروريًا من الناحية الفنية للأجهزة التي تعمل بالإصدار 4.0 من نظام التشغيل Android أو الإصدارات الأحدث في حال استخدام ميزة "الاقتراحات المطبّقة تلقائيًا":

<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>

باستخدام فلتر الأهداف هذا، يمكن تشغيل تطبيق com.example.android.beam الآن عندما يفحص علامة NFC أو يتلقى شعاع Android به نوع AAR من النوع com.example.android.beam، أو عندما تحتوي رسالة بتنسيق NDEF على سجلّ MIME من النوع application/vnd.com.example.android.beam.

على الرغم من أنّ الردود داخل التطبيق (AAR) تضمن بدء تشغيل التطبيق أو تنزيله، يوصى باستخدام فلاتر الأهداف، لأنّها تتيح لك بدء نشاط من اختيارك في تطبيقك بدلاً من بدء النشاط الرئيسي دائمًا ضمن الحزمة التي تحدّدها هذه الميزة. لا تتضمّن "الاقتراحات المطبّقة تلقائيًا" دقة على مستوى النشاط. وبما أنّ بعض الأجهزة التي تعمل بنظام التشغيل Android لا تتوافق مع "الاقتراحات المطبّقة تلقائيًا"، عليك أيضًا تضمين معلومات تعريفية في سجلّ NDEF الأوّل من رسائل NDEF والفلترة للاطّلاع عليها أيضًا، في حال حدوث ذلك. راجع إنشاء أنواع شائعة من سجلات NDEF لمزيد من المعلومات حول كيفية إنشاء السجلات.