2013-05-29 506 views
13

我是Android新手NFC API。從NFC標籤(IsoDep)讀取數據

目前,我有一個NFC標籤,我正在製作一個Android應用程序來從中讀取數據。當我的手機距離NFC標籤足夠近時,我的簡單應用便會啓動。但我不知道如何讀取NFC標籤內的數據。該標籤使用IsoDep技術。

我當前的代碼:

@Override 
protected void onResume(){ 
    super.onResume(); 

    Intent intent = getIntent(); 
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 

    IsoDep isoDep = IsoDep.get(tag); 

    // How to read data from IsoDep instance? 

我用Google搜索互聯網上,我注意到人們將命令發送到IsoDep擺脫NFC標籤的響應,我從響應假設,我們可以在標籤解析數據,我看到人們這樣做:

//What is the 'command' ? How to define the command? 
//e.g.: 
byte command = (byte) 0x6A 
isoDep.transceive(command) 

但是,該命令只是一個byte,作爲一個新手,實在很難理解發生了什麼。我不知道如何定義命令來讀取數據?任何人都可以向我解釋?或者是否有我可以瞭解該命令的文檔?

一般來說,我需要關於如何定義命令&如何解析從響應數據的一些指導,我想讀取存儲在標籤&數據顯示在UI單元(例如TextView)在字符串格式的數據。

*和***

我有那些配置沒問題(如AnroidManifest.xml),請不要引導我如何配置:)

回答

14

IsoDep讓你通過ISO-14443-4連接與transceive操作進行通信。在此協議上交換應用程序數據單元(APDU)。格式是指定的,您可以在Wikipedia.

中找到說明例如,要選擇具有特定應用程序標識符(AID)的智能卡上的應用程序,您將執行以下APDU命令。結果僅表示ok(9000)或錯誤。

byte[] SELECT = { 
     (byte) 0x00, // CLA Class   
     (byte) 0xA4, // INS Instruction  
     (byte) 0x04, // P1 Parameter 1 
     (byte) 0x00, // P2 Parameter 2 
     (byte) 0x0A, // Length 
     0x63,0x64,0x63,0x00,0x00,0x00,0x00,0x32,0x32,0x31 // AID 
    }; 

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
    IsoDep tag = IsoDep.get(tagFromIntent); 

    tag.connect(); 
    byte[] result = tag.transceive(SELECT); 
    if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00)) 
     throw new IOException("could not select applet"); 

選擇應用程序後,您可以執行特定於應用程序的命令。這些程序通常採用遵循GlobalPlatorm規範的JavaCard編寫。以下示例在上述選定應用程序上執行方法4(0x04),該方法返回最多11個字節的字節數組。這個結果然後被轉換成一個字符串。

byte[] GET_STRING = { 
     (byte) 0x80, // CLA Class   
     0x04, // INS Instruction 
     0x00, // P1 Parameter 1 
     0x00, // P2 Parameter 2 
     0x10 // LE maximal number of bytes expected in result 
    }; 

    result = tag.transceive(GET_STRING); 
    int len = result.length; 
    if (!(result[len-2]==(byte)0x90&&result[len-1]==(byte) 0x00)) 
     throw new RuntimeException("could not retrieve msisdn"); 

    byte[] data = new byte[len-2]; 
    System.arraycopy(result, 0, data, 0, len-2); 
    String str = new String(data).trim(); 

    tag.close(); 
+0

爲什麼「len-2」?響應結構如何,是否有任何標題?沒關係,通過維基百科鏈接找到它。 2狀態字節 –

+0

[APDU](https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit)消息的結果包含響應數據(特定於應用程序),隨後是對命令進行編碼的響應尾部SW1-SW2處理結果,例如例如0x9000成功。響應數據的任何結構都是特定於應用程序的(通常使用[TLV](https://en.wikipedia.org/wiki/Type-length- value)編碼)。 – Dominik

+0

嘿多米尼克,你爲什麼選擇「方法4」它可能是任何字節? –