NFC通信

引言

NFC,即Near Field Communication,近距離無線通訊技術(shù),是一種短距離的(通常<=4cm或更短)高頻(13.56M Hz)無線通信技術(shù),它提供了一種簡單、觸控式的解決方案,可以讓消費(fèi)者簡單直觀地交換信息、訪問內(nèi)容與服務(wù)。NFC技術(shù)是由非接觸式射頻識(shí)別(RFID)及互連互通技術(shù)整合演變而來,通過在單一芯片上集成感應(yīng)式讀卡器、感應(yīng)式卡片和點(diǎn)對(duì)點(diǎn)通信的功能,利用移動(dòng)終端實(shí)現(xiàn)移動(dòng)支付、電子票務(wù)、門禁、移動(dòng)身份識(shí)別、防偽等應(yīng)用。

NFC技術(shù)

工作模式

NFC根據(jù)業(yè)務(wù)模式不同大概分為三種模式。
(1)讀卡器模式
??數(shù)據(jù)在NFC芯片中,可以簡單理解成“刷標(biāo)簽”。本質(zhì)上就是通過支持NFC的手機(jī)或其它電子設(shè)備從帶有NFC芯片的標(biāo)簽、貼紙、名片等媒介中讀寫信息。通常NFC標(biāo)簽是不需要外部供電的。當(dāng)支持NFC的外設(shè)向NFC讀寫數(shù)據(jù)時(shí),它會(huì)發(fā)送某種磁場,而這個(gè)磁場會(huì)自動(dòng)的向NFC標(biāo)簽供電。
(2)仿真卡模式
??數(shù)據(jù)在支持NFC的手機(jī)或其它電子設(shè)備中,可以簡單理解成“刷手機(jī)”。本質(zhì)上就是將支持NFC的手機(jī)或其它電子設(shè)備當(dāng)成借記卡、公交卡、門禁卡等IC卡使用?;驹硎菍⑾鄳?yīng)IC卡中的信息憑證封裝成數(shù)據(jù)包存儲(chǔ)在支持NFC的外設(shè)中 。
在使用時(shí)還需要一個(gè)NFC射頻器(相當(dāng)于刷卡器)。將手機(jī)靠近NFC射頻器,手機(jī)就會(huì)接收到NFC射頻器發(fā)過來的信號(hào),在通過一系列復(fù)雜的驗(yàn)證后,將IC卡的相應(yīng)信息傳入NFC射頻器,最后這些IC卡數(shù)據(jù)會(huì)傳入NFC射頻器連接的電腦,并進(jìn)行相應(yīng)的處理(如電子轉(zhuǎn)帳、開門等操作)。
(3)點(diǎn)對(duì)點(diǎn)模式
??該模式與藍(lán)牙、紅外差不多,用于不同NFC設(shè)備之間進(jìn)行數(shù)據(jù)交換,不過這個(gè)模式已經(jīng)沒有有“刷”的感覺了。其有效距離一般不能超過4厘米,但傳輸建立速度要比紅外和藍(lán)牙技術(shù)快很多,傳輸速度比紅外塊得多,如過雙方都使用Android4.2,NFC會(huì)直接利用藍(lán)牙傳輸。這種技術(shù)被稱為Android Beam。所以使用Android Beam傳輸數(shù)據(jù)的兩部設(shè)備不再限于4厘米之內(nèi)。
??點(diǎn)對(duì)點(diǎn)模式的典型應(yīng)用是兩部支持NFC的手機(jī)或平板電腦實(shí)現(xiàn)數(shù)據(jù)的點(diǎn)對(duì)點(diǎn)傳輸,例如,交換圖片或同步設(shè)備聯(lián)系人。因此,通過NFC,多個(gè)設(shè)備如數(shù)字相機(jī),計(jì)算機(jī),手機(jī)之間,都可以快速連接,并交換資料或者服務(wù)。

重要參數(shù)

  1. 有效傳輸范圍<=4cm
  2. 傳輸速度有三種:106kbps;?212kbps;?424kbps
  3. 建立連接時(shí)間<1s
  4. NFC工作頻率為13.65兆赫茲

開發(fā)流程

NFC標(biāo)簽的復(fù)雜度不一。簡單的標(biāo)簽僅能夠提供讀寫語義,有時(shí)編程域是一次性的,寫完卡片就變成只讀。更復(fù)雜一點(diǎn)的tag能夠提供數(shù)學(xué)運(yùn)算,擁有加密硬件保護(hù)區(qū)塊的訪問。最最復(fù)雜的tag包含操作環(huán)境,允許tag上執(zhí)行的代碼進(jìn)行交互。我們還能夠以各種格式來向tag中寫入存儲(chǔ)數(shù)據(jù),但很多Android的API框架都是基于NFC論壇制定的NDEF標(biāo)準(zhǔn)。

添加NFC權(quán)限

首先,在AndroidManifests.xml中聲明NFC和添加相應(yīng)的權(quán)限。

<uses-feature  android:name="android.hardware.nfc"  
        android:required="true" />  
<uses-permission android:name="android.permission.NFC" />

添加識(shí)別NFC標(biāo)簽

NFC有三種過濾器分別是ACTION_NDEF_DISCOVERED,ACTION_TECH_DISCOVERED,ACTION_TAG_DISCOVERED。

  1. ACTION_NDEF_DISCOVERED

當(dāng)掃描到的tag中包含有NDEF載荷且為已知類型,該intent將用來啟動(dòng)Activity。該intent的優(yōu)先級(jí)最高,tag分發(fā)系統(tǒng)總是先于其他intent用該intent來啟動(dòng)Activity。

  1. ACTION_TECH_DISCOVERED

如果manifest中沒有注冊(cè)處理ACTION_NDEF_DISCOVERED類型的intent,該intent將被用以啟動(dòng)Activity。如果tag中沒有包含可以映射到MIME或者URI類型的數(shù)據(jù),或者雖然沒有包含NDEF數(shù)據(jù),但是已知的tag技術(shù),則該intent也會(huì)被直接啟用。

  1. ACTION_TAG_DISCOVERED

如果沒有上述兩個(gè)intent,那么該intent就會(huì)啟動(dòng)。

當(dāng)android設(shè)備掃描到一個(gè)NFC標(biāo)簽時(shí),會(huì)自動(dòng)尋找最適合的Activity來處理這個(gè)Tag。在Activity中添加intent-filter標(biāo)簽,當(dāng)掃描到NFC設(shè)備時(shí)系統(tǒng)會(huì)打開此Activity。

1.ACTION_NDEF_DISCOVERED過濾器定義如下:


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

2.ACTION_TECH_DISCOVERED過濾器定義如下:

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

filter_nfc.xml文件

<?xml version="1.0" encoding="utf-8" ?>
 <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-list>
      <tech-list>
        <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>

MIFARE Classic數(shù)據(jù)格式就是NfcA,MIFARE DESFire數(shù)據(jù)格式是IsoDep(交通卡),NfcB(身份證),Felica用的就是NfcF,德州儀器的VicinityCard卡用的是NfcV,而Android分享文件就是實(shí)用的Ndef格式傳輸數(shù)據(jù)。

3.ACTION_TAG_DISCOVERED過濾器定義如下:

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

初始化適配器

NFC開發(fā)需要使用安卓系統(tǒng)提供的NfcAdapter對(duì)象,使用該對(duì)象管理NFC設(shè)備。

//獲取NfcAdapter對(duì)象,此方法與獲取藍(lán)牙適配器對(duì)象類似
 mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
        if (mNfcAdapter == null) {
            Toast.makeText(this, "該設(shè)備不支持nfc", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        if (!mNfcAdapter.isEnabled()) {
            startActivity(new Intent("android.settings.NFC_SETTINGS"));
            Toast.makeText(this, "設(shè)備未開啟nfc", Toast.LENGTH_SHORT).show();
        }

啟用NFC前臺(tái)調(diào)度

在Activity的onResume方法中打開前臺(tái)調(diào)度。

@Override
    protected void onResume() {
        super.onResume();
        //一旦截獲NFC消息,就會(huì)通過PendingIntent調(diào)用窗口
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter[] intentFilters = new IntentFilter[]{};
        //用于打開前臺(tái)調(diào)度(擁有最高的權(quán)限),當(dāng)這個(gè)Activity位于前臺(tái)(前臺(tái)進(jìn)程),即可調(diào)用這個(gè)方法開啟前臺(tái)調(diào)度
        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);
    }

接收數(shù)據(jù)

當(dāng)手機(jī)端檢測接收到NFC設(shè)備數(shù)據(jù)時(shí),在onNewIntent方法中即可接受到數(shù)據(jù)。在onNewIntent方法參數(shù)intent對(duì)象中獲取數(shù)據(jù)。

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())
                || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            //讀取NFC的id
            String id = ByteArrayToHexString(tag.getId());

            //獲取tag中的數(shù)據(jù)信息
            String[] tagTechList = tag.getTechList();
            if (tagTechList != null) {
                for (int i = 0; i < tagTechList.length; i++) {
                    stringBuilder.append("*").append(tagTechList[i]).append("*").append("\n");
                    stringBuilder.append(readTech(tag, tagTechList[i],intent));
                }
            }
            Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);  
            if (rawArray != null) {
                //獲取NDEF描述信息
                NdefMessage mNdefMsg = (NdefMessage) rawArray[0];
                //獲取NDEF記錄信息
                NdefRecord mNdefRecord = mNdefMsg.getRecords()[0];
                if (mNdefRecord != null) {
                    String readResult = new String(mNdefRecord.getPayload(), "UTF-8");
                }
            }
        }
    }

發(fā)送數(shù)據(jù)

* 向NFC發(fā)送數(shù)據(jù)
* data要發(fā)送的數(shù)據(jù)
* intent onNewIntent方法回調(diào)的Intent對(duì)象

public static void writeNFCToTag(String data, Intent intent) throws IOException, FormatException {
        //獲取Tag對(duì)象
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        Ndef ndef = Ndef.get(tag);
        //連接
        ndef.connect();
        NdefRecord ndefRecord = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            ndefRecord = NdefRecord.createTextRecord(null, data);
        }
        //數(shù)據(jù)格式打包
        NdefRecord[] records = {ndefRecord};
        NdefMessage ndefMessage = new NdefMessage(records);
        //發(fā)送數(shù)據(jù)
        ndef.writeNdefMessage(ndefMessage);
}

關(guān)閉NFC前臺(tái)調(diào)度

之前在Activity的onResume方法中啟用NFC的前臺(tái)調(diào)度,相應(yīng)的,在onPuse方法中關(guān)閉NFC的前臺(tái)調(diào)度。

//調(diào)用disableForegroundDispatch方法關(guān)閉前臺(tái)調(diào)度
if(mNfcAdapter != null){
     mNfcAdapter.disableForegroundDispatch(this);
}

總結(jié)

NFC技術(shù)作為一種新興技術(shù)在世界范圍內(nèi)受到了廣泛關(guān)注,尤其是手機(jī)的廣泛應(yīng)用,為NFC技術(shù)的長足發(fā)展提供了前提。NFC技術(shù)原理簡單,因此成本相對(duì)低廉,除此之外NFC通信的帶寬高、能耗低等特點(diǎn)也是促進(jìn)NFC技術(shù)發(fā)展的一大優(yōu)勢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容