NFC标签的读写

概述

现在市面上所售的Android手机几乎都支持NFC功能,作为开发者有必要对其进行一番了解,NFC技术是一种短距高频的无线电技术,主要用于IOT领域。NFC在Android上,是从API9才开始支持的,但是到了API14 Google才对NFC大力开发,所以等到了API15的时候,NFC的传输速度就得到了很大的加强,所以最小api最好设置为14。它有三种模式数据交互形式:

  1. 读卡器模式(Reader/Witer Mode)
  2. 仿真卡模式(Card Emulation Mode)公交刷卡所用的方式
  3. 点对点模式(P2P Mode)共享数据所用的方式
    今天主要实现读卡器模式。

具体实现:

  1. 权限的配置

    1
    2
    3
    4
    <uses-permission android:name="android.permission.NFC" />
    <!-- 要求当前设备必须要有NFC芯片 -->
    <uses-feature android:name="android.hardware.nfc"
    android:required="true" />
  2. 当我们在注册activity的时候还需要加上过滤NFC的intent,目的是一旦NFC标签靠近手机,手机发起响应不能让它调起系统自带的NFC应用,而是我们的应用

    1
    2
    3
    <intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
    </intent-filter>
  3. 定义NFC标签的规则标准,目的是哪些符合标准的NFC标签可以让自己的应用响应。该标准由xml文件编写,例如创建一个nfc_model.xml的文件。该文件放在rew资源中的xml文件夹中

    • nfc_model.xml里面的内容有:

      1
      2
      3
      4
      5
      <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
      <tech-list>
      <tech>android.nfc.tech.MifareClassic</tech>
      </tech-list>
      </resources>
    • 在注册activity时将nfc_model.xml文件添加进去:

      1
      2
      <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
      android:resource="@xml/nfc_model" />
  4. 在Activity中重写onNewIntent,这里的android:launchMode为”singleTop”,要注意。对NFC标签无论是读还是写都会调用这个重写的方法,数据格式是ndef

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    @Override
    protected void onNewIntent(Intent intent) {//通过intent来作为数据的载体
    if(iswrite){//是写入
    Tag detectedTag =intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{createTextRecord(mTagText)});//写入ndef格式的字符串
    boolean result = writeTag(ndefMessage, detectedTag);
    if (result) {//写入成功
    }
    }else{//是读
    readNfcTag(intent);
    }
    }
    /**
    *读
    */
    private void readNfcTag(Intent intent) {
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {//标签靠近手机时,手机响应NFC标签
    Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
    NfcAdapter.EXTRA_NDEF_MESSAGES);//获取序列数组
    NdefMessage msgs[] = null;
    if (rawMsgs != null) {//将数组放进NdefMessage中
    msgs = new NdefMessage[rawMsgs.length];
    for (int i = 0; i < rawMsgs.length; i++) {
    msgs[i] = (NdefMessage) rawMsgs[i];
    }
    }
    NdefRecord record = msgs[0].getRecords()[0];
    String textRecord = parseTextRecord(record);
    //textRecord 就是读到的nfc标签里的字符串了
    }
    }
    /**
    * 将文本信息转成ndef格式的NdefRecord
    *
    * @param text
    * @return
    */
    protected NdefRecord createTextRecord(String text) {
    byte[] langBytes = Locale.CHINA.getLanguage().getBytes(Charset.forName("US-ASCII"));
    Charset utfEncoding = Charset.forName("UTF-8");
    //将文本转换为UTF-8格式
    byte[] textBytes = text.getBytes(utfEncoding);
    //设置状态字节编码最高位数为0
    int utfBit = 0;
    //定义状态字节
    char status = (char) (utfBit + langBytes.length);
    byte[] data = new byte[1 + langBytes.length + textBytes.length];
    //设置第一个状态字节,先将状态码转换成字节
    data[0] = (byte) status;
    //设置语言编码,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1到langBytes.length的位置
    System.arraycopy(langBytes, 0, data, 1, langBytes.length);
    //设置文本字节,使用数组拷贝方法,从0开始拷贝到data中,拷贝到data的1 + langBytes.length
    //到textBytes.length的位置
    System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
    //通过字节传入NdefRecord对象
    //NdefRecord.RTD_TEXT:传入类型 读写
    NdefRecord ndefRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_TEXT, new byte[0], data);
    return ndefRecord;
    }
  5. 这里以Ndef开头的两个类,都是核心类:NdefMessage:主要是描述NDEF格式的信息。NdefRecord:这个是秒速NDEF信息的一个信息段。有了读和写,我们就能进行基本的数据交互。十分的简单。NFC标签属于IOT的范畴,有很多种的用途。更多的逻辑处理是在于读写的操作上。标签里如果需要存在大量的数据的话,需要把写入的文本数据写成json格式的字符串,再通过手机获取信息发送的服务器。


------ 本文结束 ------

版权声明

文章作者: 周 康

发布时间: 2017年01月19日 - 15:01

原始链接: http://Kanging.github.io/2017/01/19/NFCforAndroid/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。