أساسيات تقنية 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 عند فتح قفل الشاشة، إلا إذا كانت تقنية 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 على الحقول التالية:

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

يستخدِم نظام إرسال العلامات حقلَي TNF والنوع لمحاولة ربط نوع 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 للحصول على مزيد من المعلومات حول مواعيد الإرسال والاستقبال المتاحة وربطاتها.

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

إجراء_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 وNdef أو الترميزتين NfcB وNdef:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>

في ملف AndroidManifest.xml، حدِّد ملف المورد الذي أنشأته للتو في العنصر <meta-data> داخل العنصر <activity> كما في المثال التالي:

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

<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
    android:resource="@xml/nfc_tech_filter" />
...
</activity>

لمزيد من المعلومات حول استخدام تقنيات العلامات والغرض من ACTION_TECH_DISCOVERED، يُرجى الاطّلاع على التعامل مع تقنيات العلامات المتوافقة في مستند NFC المتقدّم.

تم اكتشاف إجراء_TAG_TAG

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

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

TNF_ABSOLUTE_URI

ملاحظة: ننصح باستخدام النوع RTD_URI بدلاً من TNF_ABSOLUTE_URI لأنّه أكثر فعالية.

يمكنك إنشاء سجلّ NDEF TNF_ABSOLUTE_URI على النحو التالي :

Kotlin

val uriRecord = ByteArray(0).let { emptyByteArray ->
    NdefRecord(
            TNF_ABSOLUTE_URI,
            "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")),
            emptyByteArray,
            emptyByteArray
    )
}

Java

NdefRecord uriRecord = new NdefRecord(
    NdefRecord.TNF_ABSOLUTE_URI ,
    "https://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
    new byte[0], new byte[0]);

سيظهر فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="https"
        android:host="developer.android.com"
        android:pathPrefix="/index.html" />
</intent-filter>

TNF_MIME_MEDIA

يمكنك إنشاء سجلّ NDEF واحد (TNF_MIME_MEDIA) بالطرق التالية:

باستخدام طريقة createMime():

Kotlin

val mimeRecord = NdefRecord.createMime(
        "application/vnd.com.example.android.beam",
        "Beam me up, Android".toByteArray(Charset.forName("US-ASCII"))
)

Java

NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam",
    "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));

إنشاء NdefRecord يدويًا:

Kotlin

val mimeRecord = Charset.forName("US-ASCII").let { usAscii ->
    NdefRecord(
            NdefRecord.TNF_MIME_MEDIA,
            "application/vnd.com.example.android.beam".toByteArray(usAscii),
            ByteArray(0),
            "Beam me up, Android!".toByteArray(usAscii)
    )
}

Java

NdefRecord mimeRecord = new NdefRecord(
    NdefRecord.TNF_MIME_MEDIA ,
    "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
    new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));

سيظهر فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="application/vnd.com.example.android.beam" />
</intent-filter>

TNF_WELL_KNOWN مع RTD_TEXT

يمكنك إنشاء سجلّ NDEF واحد (TNF_WELL_KNOWN) بالطريقة التالية:

Kotlin

fun createTextRecord(payload: String, locale: Locale, encodeInUtf8: Boolean): NdefRecord {
    val langBytes = locale.language.toByteArray(Charset.forName("US-ASCII"))
    val utfEncoding = if (encodeInUtf8) Charset.forName("UTF-8") else Charset.forName("UTF-16")
    val textBytes = payload.toByteArray(utfEncoding)
    val utfBit: Int = if (encodeInUtf8) 0 else 1 shl 7
    val status = (utfBit + langBytes.size).toChar()
    val data = ByteArray(1 + langBytes.size + textBytes.size)
    data[0] = status.toByte()
    System.arraycopy(langBytes, 0, data, 1, langBytes.size)
    System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size)
    return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), data)
}

Java

public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
    byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
    Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
    byte[] textBytes = payload.getBytes(utfEncoding);
    int utfBit = encodeInUtf8 ? 0 : (1 << 7);
    char status = (char) (utfBit + langBytes.length);
    byte[] data = new byte[1 + langBytes.length + textBytes.length];
    data[0] = (byte) status;
    System.arraycopy(langBytes, 0, data, 1, langBytes.length);
    System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
    NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_TEXT, new byte[0], data);
    return record;
}

سيظهر فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
</intent-filter>

TNF_WELL_KNOWN باستخدام RTD_URI

يمكنك إنشاء سجلّ NDEF واحد (TNF_WELL_KNOWN) بالطرق التالية:

باستخدام طريقة createUri(String):

Kotlin

val rtdUriRecord1 = NdefRecord.createUri("https://example.com")

Java

NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");

باستخدام طريقة createUri(Uri):

Kotlin

val rtdUriRecord2 = Uri.parse("https://example.com").let { uri ->
    NdefRecord.createUri(uri)
}

Java

Uri uri = Uri.parse("https://example.com");
NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);

إنشاء NdefRecord يدويًا:

Kotlin

val uriField = "example.com".toByteArray(Charset.forName("US-ASCII"))
val payload = ByteArray(uriField.size + 1)                   //add 1 for the URI Prefix
payload [0] = 0x01                                           //prefixes https://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.size)     //appends URI to payload
val rtdUriRecord = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, ByteArray(0), payload)

Java

byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1];              //add 1 for the URI Prefix
payload[0] = 0x01;                                           //prefixes https://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length);  //appends URI to payload
NdefRecord rtdUriRecord = new NdefRecord(
    NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);

سيظهر فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="https"
        android:host="example.com"
        android:pathPrefix="" />
</intent-filter>

TNF_EXTERNAL_TYPE

يمكنك إنشاء سجلّ NDEF TNF_EXTERNAL_TYPE بالطرق التالية:

باستخدام طريقة createExternal():

Kotlin

var payload: ByteArray //assign to your data
val domain = "com.example" //usually your app's package name
val type = "externalType"
val extRecord = NdefRecord.createExternal(domain, type, payload)

Java

byte[] payload; //assign to your data
String domain = "com.example"; //usually your app's package name
String type = "externalType";
NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);

إنشاء NdefRecord يدويًا:

Kotlin

var payload: ByteArray
...
val extRecord = NdefRecord(
        NdefRecord.TNF_EXTERNAL_TYPE,
        "com.example:externalType".toByteArray(Charset.forName("US-ASCII")),
        ByteArray(0),
        payload
)

Java

byte[] payload;
...
NdefRecord extRecord = new NdefRecord(
    NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")),
    new byte[0], payload);

سيظهر فلتر الأهداف لسجلّ NDEF السابق على النحو التالي:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="vnd.android.nfc"
        android:host="ext"
        android:pathPrefix="/com.example:externalType"/>
</intent-filter>

استخدِم TNF_EXTERNAL_TYPE لعمليات نشر علامات NFC أكثر عمومية للتوافق بشكل أفضل مع الأجهزة التي تعمل بنظام التشغيل Android وتلك التي لا تعمل بنظام التشغيل Android.

ملاحظة: أرقام URN TNF_EXTERNAL_TYPE بتنسيق أساسي على النحو التالي: urn:nfc:ext:example.com:externalType، ومع ذلك، تشير مواصفات "المراسلة النصية في الوقت الفعلي" في منتدى NFC إلى أنّه يجب حذف الجزء 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 (AAR) تأكيدًا أقوى على بدء تشغيل تطبيقك عندما يتم مسح علامة 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 تكون خاصة بأجهزة Android 4.0 أو الإصدارات الأحدث، لذلك عند نشر العلامات، ستحتاج على الأرجح إلى استخدام مزيج من أنواع AAR وMIME/معرّفات الموارد المنتظمة (URI) للتوافق مع أوسع نطاق من الأجهزة. فضلاً عن ذلك، عند نشر علامات NFC، فكّر في طريقة كتابة علامات NFC لإتاحة التوافق مع معظم الأجهزة (التي تعمل بنظام التشغيل Android والأجهزة الأخرى). ويمكنك القيام بذلك عن طريق تحديد نوع MIME أو عنوان URI فريد نسبيًا لتسهيل تمييز التطبيقات.

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

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

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