Detailed explanation of Android NFC

1,NFCOverview

        NFC, the full name is Near Field Communication, which is near field communication, also called short rangewireless communication technology. Devices using NFC technology (such as mobile phones) can exchange data when close to each other, which is controlled by contactless radio frequency identification (RFID) Evolved from the integration of interconnection and interoperability technologies, by integrating the functions of inductive card readers, inductive cards and point-to-point communication on a single chip, mobile terminals are used to realize mobile payment, electronic ticketing, access control, mobile identity recognition, anti-counterfeiting, etc. application.

2. NFC working principle

        NFC is a short-range, high-frequency radio technology. The NFCIP-1 standard stipulates that the communication distance of NFC is within 10 cm, the operating frequency is 13.56MHz, and the transmission speed is 106Kbit/s, 212Kbit/s or 424Kbit/s. Three types. The NFCIP-1 standard specifies in detail the transmission speed, codec method, modulation scheme and frame format of the RF interface of NFC devices. This standard also defines NFC Transmission protocol, including startup protocol and data exchange method.

        NFC working modes are divided into passive mode and active mode.

        1) Passive mode

        In passive mode, the NFC initiating device (also called the master device) requires a power supply device. The master device uses the energy of the power supply device to provide a radio frequency field and sends data to the NFC target device (also called a slave device). The transmission rate needs to be selected from 106kbps, 212kbps or 424kbps. The slave device does not generate radio frequency fields, so it does not need a power supply device. Instead, it uses the RF field generated by the master device to convert it into electrical energy for the circuit of the slave device. It supplies power, receives data sent by the master device, and uses load modulation technology to transmit data from the device back to the master device at the same speed. Because the slave device does not generate a radio frequency field in this working mode, but passively receives the radio frequency field generated by the master device, it is called passive mode. In this mode, the NFC master device can detect contactless cards or NFC target devices, and to establish a connection.

        ​ ​ 2) Active mode

        In active mode, both the initiating device and the target device must actively generate radio frequency fields when sending data to each other, so it is called active mode. They both require power supply equipment to provide the energy to generate radio frequency fields. This communication mode is the standard mode for peer-to-peer network communication and can achieve very fast connection rates

3. NFC application on Android

        Near Field Communications (NFC) is a set of short-range wireless technologies that allow you to share a small payload between an NFC tag and an Android device, or between two Android devices.

        tags may vary in complexity. Simple tags only provide read and write semantics, and a one-time programmable region can sometimes be used to set the card to read-only. More complex tags can provide mathematical operations and can also use cryptographic hardware to verify access to sectors. The most complex tags can contain operating environments, allowing complex interactions with the code that executes against the tag. The data stored in the tag can also be written in a variety of formats, but many Android framework APIs are based on the NFC Forum Standard.

NFC-enabled Android devices also support the followingthree primary operating modes:

  1. Reader/Writer Mode: Enables NFC devices to read and/or write passive NFC tags and stickers.
  2. Peer-to-Peer Mode: Enables NFC devices to exchange data with other NFC peers; this mode of operation is used by Android Beam.
  3. Card emulation mode: Supports NFC device itself acting as an NFC card. The simulated NFC card can then be accessed through an external NFC reader, such as an NFC point-of-sale terminal.

        ​ ​ 1) Basic NFC tasks

There are two main use cases when using NDEF data with Android:

  • Read NDEF data from NFC tag
  • Transfer NDEF messages from one device to another using Android Beam™

        Reading NDEF data from NFC tags is handled by the tag scheduling system, which analyzes the discovered NFC tags, classifies the corresponding data appropriately, and launches applications interested in the classified data. If an app wants to process a scanned NFC tag, it can declare an intent filter and request processing of the data.

        ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​​This interaction provides an easier way to send data compared to other wireless technologies such as Bluetooth because there is no need to manually discover and pair devices when using NFC. When the distance between two devices is within a certain range, the system will automatically start connecting. Android Beam functionality is provided through a set of NFC APIs so any app can transfer information between devices. For example, Contacts, Browser, and YouTube apps can use Android Beam to share contact information, web pages, and videos across multiple devices.

        Tag scheduling system

        Android devices typically look for NFC tags when the screen is unlocked, unless NFC is disabled in the device's Settings menu. After an Android device discovers an NFC tag, the desired behavior is to have the most appropriate activity handle the intent, rather than asking the user which app should be used.

        To help you achieve this, Android provides a special tag dispatching system that analyzes scanned NFC tags, parses them and tries to find applications that are interested in the scanned data. This tag scheduling system achieves these goals by:

  1. Parses the NFC tag and determines the MIME type or URI that identifies the data payload in the tag.
  2. Encapsulate a MIME type or URI into an intent along with the payload.
  3. Start an activity based on an intent.

How to map NFC tags to MIME types and URIs

        Before you start writing an NFC application, it's important to understand the different types of NFC tags, how the tag dispatch system interprets NFC tags, and the special work the tag dispatch system performs when it detects an NDEF message. NFC tags involve a variety of technologies, and data can be written to an NFC tag in many different ways. Android has the most complete support for the NDEF standard defined by the NFC Forum.

        NDEF data is encapsulated in a message (NdefMessage) containing one or more records (NdefRecord). Each NDEF record must be well-formed and conform to the specifications for the type of record you are creating. Android also supports other types of tags that do not contain NDEF data, which you can handle using classes in the android.nfc.tech package. When dealing with these other types of tags, you'll need to write your own protocol stack to communicate with the tags, so we recommend using NDEF whenever possible to simplify development while maximizing support for Android devices.

        Note: To download the complete NDEF specification, go to NFC Forum Specification and Application Document website to see examples of how to construct NDEF records.

        Now that you have some background on NFC tags, the following sections will detail how Android handles NDEF-formatted tags. When an Android device scans an NFC tag that contains NDEF-formatted data, it parses the message and attempts to determine the MIME type or identifying URI of the data. To do this, the system needs to read the first NdefRecord in the NdefMessage to determine how to interpret the entire NDEF message (an NDEF message may have multiple NDEF records). In a well-formed NDEF message, the first NdefRecord contains the following fields:

        a), 3-digit TNF (type name format)

Indicates how to interpret variable length type fields. Valid values ​​are described in Table 1.

        b), variable length type

Describes the types of records. If using TNF_WELL_KNOWN, use this field to specify the record type definition (RTD). Valid RTD values ​​are described in Table 2.

        c), variable length ID

The record's unique identifier. This field is not used often, but if you need to uniquely identify a tag, you can create an ID for it.

        d), variable length load

The actual data load you want to read or write. An NDEF message can contain multiple NDEF records, so do not assume that the entire payload is in the first NDEF record of an NDEF message.

Table 1. Supported TNFs and their mappings
Type Name Format (TNF) mapping
TNF_ABSOLUTE_URI URI based on type field.
TNF_EMPTY return ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPE A URI based on the URN in the type field. The URN is encoded in the shortened form (<domain_name>:<service_name>) into the NDEF type field. Android maps this to a URI like this: . vnd.android.nfc://ext/<domain_name>:<service_name>
TNF_MIME_MEDIA MIME type based on type field.
TNF_UNCHANGED is not valid in the first record, so it falls back to ACTION_TECH_DISCOVERED.
TNF_UNKNOWN return ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWN MIME type or URI, depending on the record type definition (RTD) you set in the Type field. For details on the available RTDs and their mappings, seeTable 2.
Table 2. TNF_WELL_KNOWN supported RTDs and their mappings
Record type definition (RTD) mapping
RTD_ALTERNATIVE_CARRIER return ACTION_TECH_DISCOVERED.
RTD_HANDOVER_CARRIER return ACTION_TECH_DISCOVERED.
RTD_HANDOVER_REQUEST return ACTION_TECH_DISCOVERED.
RTD_HANDOVER_SELECT return ACTION_TECH_DISCOVERED.
RTD_SMART_POSTER URI based on payload parsing results.
RTD_TEXT text/plain The MIME type of .
RTD_URI Payload-based URI.

        The tag dispatch system uses TNF and type fields to attempt to map MIME types or URIs to NDEF messages. If the mapping is successful, it encapsulates the relevant information into the ACTION_NDEF_DISCOVERED Intent along with the actual payload. However, in some cases, the tag dispatch system cannot determine the type of data based on the first NDEF record. This occurs if the NDEF data cannot be mapped to a MIME type or URI, or if the NFC tag does not contain NDEF data. In such cases, the tag dispatching system will instead encapsulate the Tag object and payload containing tag technology-related information into the ACTION_TECH_DISCOVERED Intent.

        Table 1 describes how the tag dispatch system maps TNF and type fields to MIME types or URIs, and also describes which TNFs cannot be mapped to MIME types or URIs. If it cannot be mapped, the tag scheduling system falls back to ACTION_TECH_DISCOVERED.

        For example, if the tag scheduling system encounters a record of type TNF_ABSOLUTE_URI, the variable-length type field of the record will be mapped to the URI. The tag dispatch system encapsulates this URI in the data field of the ACTION_NDEF_DISCOVERED intent, along with other information about the tag (such as payload). On the other hand, if the tag dispatching system encounters a record of type TNF_UNKNOWN, it will instead create an Intent that encapsulates information related to the tag technology.

How to distribute NFC tags to apps

After the tag dispatch system creates the Intent that encapsulates the NFC tag and its identification information, it sends the Intent to interested applications, which filter it. If more than one app can handle the intent, the system displays an activity selector for the user to choose which activity to use. The tag scheduling system defines three Intents, which are listed as follows from high to low priority:

  1. ACTION_NDEF_DISCOVERED: Use this intent to launch an activity if a tag containing an NDEF payload is scanned and its type is recognized. This is the highest-priority Intent, and the tag scheduling system will try to use this Intent to start the activity when possible, and only try other Intents when that doesn't work.
  2. ACTION_TECH_DISCOVERED: If no activity is registered to handle the ACTION_NDEF_DISCOVERED intent, the tag scheduling system attempts to use this intent to launch the app. In addition, if the scanned tag contains NDEF data that cannot be mapped to a MIME type or URI, or the tag does not contain NDEF data but uses a known tag technology, the Intent will also be launched directly (without first starting ACTION_NDEF_DISCOVERED) .
  3. ACTION_TAG_DISCOVERED: If there is no activity that handles the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intent, use this intent to start the activity.

The basic working method of the tag scheduling system is as follows:

  1. While resolving an NFC tag (ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED), try to launch an activity using an Intent created by the tag dispatch system.
  2.  If there is no Activity filtering the Intent, try to start the Activity using the next priority Intent (ACTION_TECH_DISCOVERED or ACTION_TAG_DISCOVERED) until the application filters the Intent or until the tag scheduling system has tried all possible Intents.
  3. If no intents are filtered by the app, no action is performed.
图 1.  标签调degree统统

         Whenever possible, use NDEF messages and the ACTION_NDEF_DISCOVERED Intent because it is the most specific of the three Intents. This intent allows you to launch your app at a more appropriate time than the other two intents, giving users a better experience.

        Request NFC access in Android manifest

        Before you can access the device's NFC hardware and properly handle NFC Intents, you must declare the following in the AndroidManifest.xml file:

  • NFC <uses-permission> element for accessing NFC hardware:
    <uses-permission android:name="android.permission.NFC" />
  • Minimum SDK version supported by your app. API level 9 only supports limited tag dispatch via ACTION_TAG_DISCOVERED and only provides access to NDEF messages via the EXTRA_NDEF_MESSAGES extra. No other tag properties or I/O operations can be accessed. API level 10 provides full reader/writer support and front-end NDEF push capabilities; API level 14 provides an easier way (i.e., using Android Beam to push NDEF messages to other devices) and provides Additional convenience methods for creating NDEF records.
    <uses-sdk android:minSdkVersion="10"/>
  • uses-feature element so that your app appears in Google Play only on those devices with NFC hardware:
    <uses-feature android:name="android.hardware.nfc" android:required="true" />

         If your application uses the NFC function, but this function is not important for your application. You can omit the USES-Feature element, and check whether the avfc availability of NFC by checking whether the getDefaultAdapter () is null.

        Filter NFC Intent

        To launch your app when the NFC tag you intend to handle is scanned, your app can filter one, two, or all three NFC intents in the Android manifest. However, you usually want to filter the ACTION_NDEF_DISCOVERED intent to have the most control over when your app starts. If no ACTION_NDEF_DISCOVERED filtering is applied, or the payload is not NDEF, the ACTION_TECH_DISCOVERED intent supersedes ACTION_NDEF_DISCOVERED. ACTION_TAG_DISCOVERED is usually too general to be suitable for filtering. Many applications filter ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED before filtering ACTION_TAG_DISCOVERED, resulting in a lower probability of your application starting. Filtering ACTION_TAG_DISCOVERED is an application's last resort in the event that no other application handles the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intent.

        Since NFC tag deployments vary and many times they are not under your control, ACTION_NDEF_DISCOVERED may not be available every time and you can fall back to the other two intents if needed. If you have control over the label and the type of data written, it is recommended that you use NDEF to format the label. The following sections describe how to filter various types of intents.

  • ACTION_NDEF_DISCOVERED

        To filter ACTION_NDEF_DISCOVERED intents, declare the intent filter and the data type to filter. The following example shows how to filter ACTION_NDEF_DISCOVERED intents with MIME type 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>

        The following example shows how to filter URIs of the form 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="http"
                  android:host="developer.android.com"
                  android:pathPrefix="/index.html" />
    </intent-filter>
  • ACTION_TECH_DISCOVERED

        If your activity filters the ACTION_TECH_DISCOVERED intent, you must create an XML resource file that specifies the technologies your activity supports in the tech-list set. If the tech-list set is a subset of the technologies supported by the tag (which can be obtained by calling getTechList()), your activity is considered a match.

        For example, if the scanned tags support MifareClassic, NdefFormatable, and NfcA, in order for them to match your activity, your tech-list set must specify all three technologies, or two or one of them.

        The following examples define all technologies. You can remove technology you don't need. Save this file (you can name it whatever you want) to the <project-root>/res/xml folder.

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

        You can also specify multiple tech-list sets. Each tech-list set is independent; if any tech-list set is a subset of the technologies returned by getTechList(), your activity is considered a match. This provides AND and OR semantics for matching techniques. The following examples show how to match tags that support NfcA and Ndef technologies or tags that support NfcB and Ndef technologies:

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

        In your AndroidManifest.xml file, specify the resource file you just created in the  element of the <activity> element , as shown in the following example: <meta-data>

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

        For more information about using tag technologies and the ACTION_TECH_DISCOVERED Intent, see Using Supported Tag Technologies in the Advanced NFC documentation (written later).

  • ACTION_TAG_DISCOVERED

        To filter ACTION_TAG_DISCOVERED, use the following intent filter:

    <intent-filter>
        <action android:name="android.nfc.action.TAG_DISCOVERED"/>
    </intent-filter>
  • Get information from Intent

        If an activity starts due to an NFC Intent, you can get information about the scanned NFC tag from the Intent. Intents can contain the following extras, depending on the tags scanned:

  • EXTRA_TAG (required): A Tag object representing the scanned tag.
  • EXTRA_NDEF_MESSAGES (optional): A set of NDEF messages parsed from the tag. This extra is required for the ACTION_NDEF_DISCOVERED intent.
  • EXTRA_ID (optional): Low-level ID of the tag.

        To get these extras, check that your activity was launched with an NFC Intent to make sure the tag was scanned, and then get the intent's extras. The following example shows how to check for the ACTION_NDEF_DISCOVERED intent and get the NDEF message from the intent extra.

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

        ​ ​ Alternatively, you can get the Tag object from the Intent, which contains the payload and allows you to enumerate the tags:

    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Create common types of NDEF records 

        This section describes how to create common types of NDEF records to help write data to NFC tags or send data using Android Beam. Introduced to the platform starting with Android 4.0 (API level 14), the createUri() method helps you automatically create URI records. Introduced to the platform starting with Android 4.1 (API level 16), createExternal() and createMime() help you create NDEF records for MIME and external types. Use these helper methods whenever possible to avoid errors when manually creating NDEF records.

        This section also describes how to create appropriate intent filters for records. All of these NDEF record examples should be in the first NDEF record of an NDEF message you write to a tag or transmit to another device.

        a)、TNF_ABSOLUTE_URI

NOTE: It is recommended that you use the RTD_URI type instead of TNF_ABSOLUTE_URI as it is more efficient.

You can create a TNF_ABSOLUTE_URI NDEF record in the following ways:

    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]);

The Intent filter for the previous NDEF record looks like this: 

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

        b)、TNF_MIME_MEDIA 

You can create a TNF_MIME_MEDIA NDEF record in the following ways:

Use createMime() method:

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

Create NdefRecord manually:

    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")));

 The Intent filter for the previous NDEF record is as follows:

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

        c), RTD is TNF_WELL_KNOWN of RTD_TEXT
You can create a TNF_WELL_KNOWN NDEF record in the following way: 

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

The intent filter for the previous NDEF record looks like this:

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

         ​ ​ d), RTD is TNF_WELL_KNOWN of RTD_URI

You can create a TNF_WELL_KNOWN NDEF record in the following ways:

Use createUri(String) method:

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

Use createUri(Uri) method:

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

 Create NdefRecord manually:

    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 http://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);

The intent filter for the previous NDEF record looks like this:

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

        ​ ​ Use TNF_EXTERNAL_TYPE for a more generic NFC tag deployment to better support Android and non-Android devices.

        Note: The canonical format of URN for TNF_EXTERNAL_TYPE is urn:nfc:ext:example.com:externalType, but the NFC Forum RTD specification contains the following statement: The urn:nfc:ext: part of the URN must be omitted in the NDEF record . Therefore, you only need to provide the domain name ( example.com in the example) and the type ( externalType in the example), separated by a colon. When distributing TNF_EXTERNAL_TYPE , Android converts the urn:nfc:ext:example.com:externalType URN to vnd.android.nfc://ext/example.com:externalType URI, which is the URI declared by the intent filter in the example.

        e), Android Application Record
        The Android Application Record (AAR) feature was introduced in Android 4.0 (API level 14), which can more effectively ensure that when an NFC tag is scanned Start your application. AAR embeds the application's package name within the NDEF record. You can add an AAR to any NDEF record in an NDEF message because Android searches for AARs throughout the NDEF message. If an AAR is found, it launches the app based on the package name in the AAR. If the app is not available on the device, Google Play is launched for the user to download the app.

        You can use an AAR if you want to prevent other apps from filtering the same intent and potentially processing a specific tag that you have deployed. Due to package name restrictions, AAR is only supported at the application level and, like intent filtering, is not supported at the activity level. If you need to handle intents at the activity level, use intent filters.

        If the tag contains an AAR, the tag scheduling system will perform distribution as follows:

  1. Try launching the activity using the intent filter as usual. If the activity that matches the intent also matches the AAR, the activity is launched.
  2. If the activity filtering the intent does not match the AAR, or there are multiple activities that can handle the intent, or there is no activity that can handle the intent, the app specified by the AAR is launched.
  3. If none of the applications specified by the AAR can be launched, go to Google Play and ask the user to download the corresponding application according to the AAR.

        Note: You can replace the AAR and Intent dispatch systems with a foreground dispatch system to prioritize launching foreground activities after an NFC tag is discovered. When using this method, the activity must be running in the foreground to replace the AAR and intent dispatch system.

        If you still want to filter scanned tags that do not contain AARs, you can declare an intent filter as usual. This is useful if your app is interested in other tags that don't contain AARs. For example, you might need to ensure that your application can handle proprietary tags deployed by you as well as general tags deployed by third parties. Note that AARs are specific to devices running Android 4.0 or higher, so when deploying tags you will most likely need to use AARs with MIME types/URIs to support a variety of devices. Additionally, when deploying NFC tags, consider how you will write your NFC tags so that they work with most devices (Android and otherwise). You can do this by defining relatively unique MIME types or URIs, making it easier for applications to distinguish them.

        Android provides createApplicationRecord(), a simple API to create AAR. You just embed the AAR anywhere in the NdefMessage. You don't need to use the first record of the NdefMessage unless the AAR is the only record in the NdefMessage. This is because the Android system examines the first record of the NdefMessage to determine the tag's MIME type or URI, which is needed when creating the intent that the app will filter. The following code shows how to create an AAR:

    NdefMessage msg = new NdefMessage(
            new NdefRecord[] {
    
    
                ...,
                NdefRecord.createApplicationRecord("com.example.android.beam")}
            );
    )
        Transmitting NDEF messages to other devices 

        Android Beam enables simple peer-to-peer data exchange between two Android devices. Apps that need to transfer data to another device must be running in the foreground, and the device that needs to receive data must not be locked. When the transmitting device is close enough to the receiving device, the transmitting device will display the "Touch to Transmit" interface. The user can then choose whether to transmit the message to the receiving device.

        Note: Foreground NDEF push is available in API level 10 and has functionality similar to Android Beam. These APIs have since been deprecated but may be used to support older devices. For more information, see enableForegroundNdefPush().

        ​ ​ Call one of the following two methods to enable Android Beam for your app:

  • setNdefPushMessage(): Accepts an NdefMessage to set it as the message to be transmitted. Automatically transmit messages when two devices are close enough.
  • setNdefPushMessageCallback(): Accepts a callback containing createNdefMessage() (called when the device is in range to receive data). This callback enables you to create NDEF messages as needed.

        An activity can only push one NDEF message at a time, so if two NDEF messages are set, setNdefPushMessageCallback() will take precedence over setNdefPushMessage(). To use Android Beam, the following general guidelines must be met:

  • The activity transferring data must be running in the foreground. The screens of both devices must be unlocked.
  • The data to be transmitted must be encapsulated in an NdefMessage object.
  • NFC devices that receive transmitted data must support the com.android.npp NDEF push protocol or the NFC Forum's SNEP (Simple NDEF Exchange Protocol). Devices with API level 9 (Android 2.3) through API level 13 (Android 3.2) require the com.android.npp protocol. Devices with API level 14 (Android 4.0) and higher require com.android.npp and SNEP.

        Note: If your activity supports Android Beam and is running in the foreground, the standard intent dispatching system is disabled. However, if your activity also supports foreground dispatch, it can still scan for tags that match the intent filter set in the foreground dispatch.

        ​ ​ ​ To enable Android Beam, do the following:

  1. Create an NdefMessage containing an NdefRecord to be pushed to other devices.
  2. Call setNdefPushMessage() with NdefMessage, or, call setNdefPushMessageCallback, passing the NfcAdapter.CreateNdefMessageCallback object into the Activity's onCreate() method. These methods require you to enable at least one activity through Android Beam and activate an optional list of other activities. Typically, you would use setNdefPushMessage() if two devices are within communication range and your activity only needs to push the same NDEF message all the time. If your app is concerned with the current context of your app and needs to push NDEF messages based on actions the user is currently taking in your app, you can use setNdefPushMessageCallback.

        The following example shows how a simple Activity calls NfcAdapter.CreateNdefMessageCallback in the Activity's onCreate() method. This sample also provides methods to help you create MIME records:

    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()));
        }
    }

        ​ ​ ​ Note that this code adds a comment to the AAR, which you can remove. If AAR is enabled, the apps specified in the AAR always receive Android Beam messages. If the app does not exist, Google Play is launched and the user is asked to download the app. Therefore, the following intent filters are technically unnecessary for devices running Android 4.0 and above (if AAR is used): 

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

          When containing a MIME record of type  . com.example.android.beamapplication/vnd.com.example.android.beam

        Even though an AAR guarantees that your app will be launched or downloaded, we still recommend using intent filters because they allow you to launch selected activities in your app instead of always launching the main activity within the package specified by the AAR. AAR does not have activity level granularity. Additionally, because some Android devices do not support AAR, you should also embed identifying information in the first NDEF record of the NDEF message to allow for filtering if needed.

 4. Comparison between NFC and other technologies

        Current short-range wireless communication technologies includeRFID, Bluetooth,infrared, etc. NFC is a short-distance high-frequency wireless communication technology that allows non-contact point-to-point data transmission between electronic devices. . Its operating frequency is 13.56MHz, the communication distance is 0~20cm (actually most products are within 10cm), and the transmission rate can be 106kbit/s, 212kbit/s, 424 kbit/s and 848kbit/s. In addition to NFC, short-range wireless communication technology also mainly includes Radio Frequency Identification (RFID), Bluetooth (Bluetooth), ZigBee (ZigBee), infrared, Wi-Fi and other technologies. Each of the above technologies has its own characteristics and advantages. The following figure shows a comparison of the performance of NFC and six other short-range wireless communication technologies on the listed frequency bands.

    It can be seen that NFC technology has extremely high security, performance advantages in short-distance communication, and more importantly, low cost. Therefore, since its advent in 2003, it has received the attention and support of many enterprises.

        Comparison between NFC and RFID

        First, the working mode is different. NFC integrates point-to-point communication functions, reader-writer functions and contactless card functions into one chip, while RFID consists of a reader and a tag. NFC technology can both read and write, while RFID can only read and determine information. [2] 

        Second, the transmission distance is different. The transmission distance of NFC is much smaller than that of RFID. The transmission distance of NFC is only 10 centimeters, while the transmission distance of RFID can reach several meters or even dozens of meters. NFC is a short-distance private communication method. Compared with RFID, NFC has the characteristics of short distance, high bandwidth, low energy consumption, and high security. [2] 

        Third, the application fields are different. NFC is more used in the field of consumer electronics and plays a huge role in access control, public transportation, mobile payment and other fields; RFID is better at long-distance identification and is more used in production, logistics, tracking, and asset management. superior. [2] 

        Comparison of near field communication NFC and Bluetooth

        NFC and Bluetooth are both short-range communication technologies. Compared with Bluetooth, which has been integrated intomobile phones very early and has been popularized, NFC It has only started to be integrated into mobile phones in recent years, and so far only in a few mobile phones. [2] 

        First, the establishment time is different. The NFC communication setting procedure is simple and the communication establishment time is very short, only about 0.1s; while the Bluetooth communication setting procedure is relatively complex and the communication establishment time is long, about 6s. [2] 

        Second, the transmission distance is different. The NFC transmission distance is only 10cm, while the Bluetooth transmission distance can reach 10m. But NFC is slightly better than Bluetooth in terms of transmission power consumption and security. [2] 

        Third, the transmission speed and operating frequency are different. The NFC operating frequency is 13.56MHz and the maximum transmission speed is 424 Kbit/s, while the Bluetooth operating frequency is 2.4GHz and the transmission speed can reach 2.1 Mbit/s. [2] 

        Comparison of near field communication NFC and infrared

Compared with infrared transmission, NFC has the same transmission distance, but it is faster than infrared transmission. NFC transmission speed can reach up to 424 Kbit/s, while infrared transmission speed is about 100Kbit/s. The establishment time of NFC is slightly faster than that of infrared. The establishment time of NFC is 0.1s and the establishment time of infrared transmission is 0.5s. Infrared transmission must be strictly aligned to transmit data, and there must be no obstacles in the middle, while NFC does not have such restrictions; in addition, NFC is more secure and reliable than infrared.

Reprint: https://blog.csdn.net/u013164293/article/details/124474247

Guess you like

Origin blog.csdn.net/gqg_guan/article/details/134312076