【问题标题】:Read data from NFC tag (IsoDep)从 NFC 标签 (IsoDep) 读取数据
【发布时间】:2013-05-24 18:42:24
【问题描述】:

我是 Android NFC API 的新手。

目前,我有一个 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?

我在网上搜索了一下,我注意到人们正在向IsoDep 发送命令以从 NFC 标签获取响应,我想从响应中,我们可以解析标签中的数据,我看到人们这样做:

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

但是,命令只是一个byte,作为一个新手,很难理解发生了什么。我不知道如何定义读取数据的命令?谁能给我解释一下?或者有没有我可以了解该命令的文档?

一般来说,我需要一些关于如何定义命令和如何从响应中解析数据的指导,我想读取存储在标签中的数据并在 UI 元素中以字符串格式显示数据(例如TextView)。

*AND***

我对这些配置没有问题(例如AnroidManifest.xml),请不要指导我如何配置:)

【问题讨论】:

    标签: android android-intent nfc


    【解决方案1】:

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

    【讨论】:

    • 为什么是“len-2”?响应的结构如何,是否有任何标题?没关系,通过维基百科链接找到它。最后 2 个状态字节
    • APDU 消息的结果包含响应数据(特定于应用程序),后面是对命令处理结果进行编码的响应尾部 SW1-SW2,例如例如0x9000 表示成功。响应数据的任何结构都是特定于应用程序的(通常使用TLV 编码)。
    • 嗨 Dominik,你为什么选择“方法 4” 可以是任何字节吗?
    • @cherry-wave,是的,它可以是任何其他指令。可用指令由智能卡应用程序以及要使用的参数定义。
    猜你喜欢
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多