نظرة عامة على تقنية NFC المتقدمة

يتناول هذا المستند مواضيع متقدمة حول NFC، مثل العمل مع تقنيات علامات مختلفة. والكتابة إلى علامات NFC وإرسال المعلومات في المقدمة، والذي يسمح للتطبيق في المقدمة التعامل مع الأهداف حتى عند تصفية التطبيقات الأخرى لتلك التطبيقات نفسها.

التعامل مع تكنولوجيات العلامات المتوافقة

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

الجدول 1. تقنيات العلامات المسموح بها

الفئة الوصف
TagTechnology الواجهة التي يجب أن تستخدمها جميع فئات تكنولوجيا العلامات
NfcA توفّر هذه السياسة إمكانية الوصول إلى خصائص NFC-A (ISO 14443-3A) وعمليات الإدخال والإخراج.
NfcB تتيح الوصول إلى خصائص NFC-B (ISO 14443-3B) وعمليات الإدخال والإخراج.
NfcF تتيح الوصول إلى خصائص NFC-F (JIS 6319-4) وعمليات الإدخال والإخراج.
NfcV يتيح الوصول إلى خصائص NFC-V (ISO 15693) وعمليات الإدخال والإخراج.
IsoDep توفّر هذه السياسة إمكانية الوصول إلى خصائص ISO-DEP (ISO 14443-4) وعمليات الإدخال والإخراج.
Ndef تتيح الوصول إلى بيانات NDEF والعمليات التي تتم على علامات NFC التي تم تنسيقها كـ NDEF.
NdefFormatable يوفر عمليات تنسيق للعلامات التي قد تكون قابلة للتنسيق NDEF.

لا يُشترط أن تكون تقنيات العلامات التالية غير متوافقة مع الأجهزة التي تعمل بنظام التشغيل Android.

الجدول 2. تكنولوجيات العلامات المتوافقة الاختيارية

الفئة الوصف
MifareClassic يتم توفير إمكانية الوصول إلى خصائص MIFARE Classic وعمليات الإدخال/الإخراج، إذا كان جهاز Android هذا ويتوافق مع MIFARE.
MifareUltralight تتيح الوصول إلى خصائص MIFARE Ultralight وعمليات الإدخال/الإخراج إذا كان نظام Android هذا. يدعم MIFARE.

التعامل مع تكنولوجيات العلامات والهدف ACTION_TECH_DISCOVERED

عندما يفحص أحد الأجهزة علامة تتضمّن بيانات NDEF، ولكن يتعذّر ربطها بـ MIME أو معرّف موارد منتظم (URI)، يحاول نظام إرسال العلامات بدء نشاط باستخدام ACTION_TECH_DISCOVERED. والنية. يتمّ استخدام ACTION_TECH_DISCOVERED أيضًا عند العلامة بيانات غير NDEF يتم فحصها. يتيح لك الحصول على هذا الإجراء الاحتياطي استخدام البيانات في العلامة مباشرةً إذا لم يتمكن نظام إرسال العلامات من تحليلها نيابةً عنك. الخطوات الأساسية عند التعامل مع في ما يلي تكنولوجيات العلامات:

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

    Kotlin

    var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
    

    Java

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    
  3. يمكنك الحصول على نسخة افتراضية من TagTechnology من خلال استدعاء أحد get طرق المصنع للفئات في حزمة android.nfc.tech. يمكنك لعدد التكنولوجيات المتوافقة مع العلامة من خلال طلب getTechList() قبل طلب إجراء get من المصنع. على سبيل المثال، للحصول على مثيل من MifareUltralight من Tag، عليك اتّباع الخطوات التالية:

    Kotlin

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
    

    Java

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
    

قراءة العلامات والكتابة إليها

تتضمن قراءة علامة NFC والكتابة إليها الحصول على العلامة من الغرض فتح الاتصال بالعلامة. يجب تحديد حزمة البروتوكول الخاصة بك لقراءة البيانات وكتابتها. بالعلامة. مع ذلك، ضع في اعتبارك أنه لا يزال بإمكانك قراءة بيانات NDEF وكتابتها عند العمل مباشرةً بعلامة. الأمر متروك لك لكيفية هيكلة الأشياء. تشير رسالة الأشكال البيانية في المثال التالي كيفية التعامل مع علامة MIFARE Ultralight.

Kotlin

package com.example.android.nfc
import android.nfc.Tag
import android.nfc.tech.MifareUltralight
import java.io.IOException
import java.nio.charset.Charset

class MifareUltralightTagTester {

    fun writeTag(tag: Tag, tagText: String) {
        MifareUltralight.get(tag)?.use { ultralight ->
            ultralight.connect()
            Charset.forName("US-ASCII").also { usAscii ->
                ultralight.writePage(4, "abcd".toByteArray(usAscii))
                ultralight.writePage(5, "efgh".toByteArray(usAscii))
                ultralight.writePage(6, "ijkl".toByteArray(usAscii))
                ultralight.writePage(7, "mnop".toByteArray(usAscii))
            }
        }
    }

    fun readTag(tag: Tag): String? {
        return MifareUltralight.get(tag)?.use { mifare ->
            mifare.connect()
            val payload = mifare.readPages(4)
            String(payload, Charset.forName("US-ASCII"))
        }
    }
}

Java

package com.example.android.nfc;

import android.nfc.Tag;
import android.nfc.tech.MifareUltralight;
import android.util.Log;
import java.io.IOException;
import java.nio.charset.Charset;

public class MifareUltralightTagTester {

    private static final String TAG = MifareUltralightTagTester.class.getSimpleName();

    public void writeTag(Tag tag, String tagText) {
        MifareUltralight ultralight = MifareUltralight.get(tag);
        try {
            ultralight.connect();
            ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
        } catch (IOException e) {
            Log.e(TAG, "IOException while writing MifareUltralight...", e);
        } finally {
            try {
                ultralight.close();
            } catch (IOException e) {
                Log.e(TAG, "IOException while closing MifareUltralight...", e);
            }
        }
    }

    public String readTag(Tag tag) {
        MifareUltralight mifare = MifareUltralight.get(tag);
        try {
            mifare.connect();
            byte[] payload = mifare.readPages(4);
            return new String(payload, Charset.forName("US-ASCII"));
        } catch (IOException e) {
            Log.e(TAG, "IOException while reading MifareUltralight message...", e);
        } finally {
            if (mifare != null) {
               try {
                   mifare.close();
               }
               catch (IOException e) {
                   Log.e(TAG, "Error closing tag...", e);
               }
            }
        }
        return null;
    }
}

استخدام نظام الإرسال في المقدّمة

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

  1. أضِف الرمز التالي ضمن طريقة onCreate() في نشاطك:
    1. أنشِئ كائن PendingIntent قابل للتغيّر ليتمكّن نظام Android من تعبئته. بتفاصيل العلامة عند مسحها ضوئيًا.

      Kotlin

      val intent = Intent(this, javaClass).apply {
          addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
      }
      var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent,
              PendingIntent.FLAG_MUTABLE)
      

      Java

      PendingIntent pendingIntent = PendingIntent.getActivity(
          this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
          PendingIntent.FLAG_MUTABLE);
      
    2. يُرجى تعريف فلاتر الأهداف لمعالجة الأهداف التي تريد اعتراضها. المقدّمة يتحقّق نظام الإرسال من فلاتر الأهداف المحدّدة بهدف تلقّيه عند يفحص الجهاز علامة. وفي حال التطابق، سيعالج تطبيقك الهدف. إذا كان غير متطابق، يعود نظام إرسال المقدمة إلى نظام إرسال الأهداف. عند تحديد مصفوفة null من فلاتر الأهداف وفلاتر التكنولوجيا، يتم تحديد تريد فلترتها بحثًا عن كل العلامات التي تعود إلى السمة TAG_DISCOVERED والنية. يتعامل مقتطف الرمز أدناه مع جميع أنواع MIME للنطاق NDEF_DISCOVERED. إِنْتَ للتعامل مع تلك التي تحتاجها فقط.

      Kotlin

      val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
          try {
              addDataType("*/*")    /* Handles all MIME based dispatches.
                                       You should specify only the ones that you need. */
          } catch (e: IntentFilter.MalformedMimeTypeException) {
              throw RuntimeException("fail", e)
          }
      }
      
      intentFiltersArray = arrayOf(ndef)
      

      Java

      IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
          try {
              ndef.addDataType("*/*");    /* Handles all MIME based dispatches.
                                             You should specify only the ones that you need. */
          }
          catch (MalformedMimeTypeException e) {
              throw new RuntimeException("fail", e);
          }
         intentFiltersArray = new IntentFilter[] {ndef, };
      
    3. يمكنك إعداد مجموعة من تكنولوجيات العلامات التي يريد تطبيقك معالجتها. عليك استدعاء Object.class.getName() للحصول على فئة التكنولوجيا التي تريد دعمها.

      Kotlin

      techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
      

      Java

      techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
      
  2. تجاهُل عمليات الاستدعاء التالية في مراحل نشاط النشاط وأضِف منطقًا إلى تفعيل أو إيقاف إرسال البيانات في المقدّمة عند فقدان النشاط (onPause()) ويستعيد (onResume()) التركيز. يجب الاتصال بـ enableForegroundDispatch() من سلسلة التعليمات الرئيسية وفقط عندما يكون النشاط في المقدّمة (ضمان تنفيذ ذلك في onResume()) عليك أيضًا تنفيذ معاودة الاتصال "onNewIntent" لمعالجة البيانات من تقنية NFC الممسوحة ضوئيًا. .
  3. Kotlin

    public override fun onPause() {
        super.onPause()
        adapter.disableForegroundDispatch(this)
    }
    
    public override fun onResume() {
        super.onResume()
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
    }
    
    public override fun onNewIntent(intent: Intent) {
        val tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        // do something with tagFromIntent
    }
    

    Java

    public void onPause() {
        super.onPause();
        adapter.disableForegroundDispatch(this);
    }
    
    public void onResume() {
        super.onResume();
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
    }
    
    public void onNewIntent(Intent intent) {
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        // do something with tagFromIntent
    }