android - 从 NFC 标签读取数据 (IsoDep)

标签 android android-intent nfc

我是 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)

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

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

*AND***

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

最佳答案

IsoDep 允许您使用 transceive 操作通过 ISO-14443-4 连接进行通信。通过此协议(protocol)交换应用程序数据单元 (APDU)。指定了格式,您可以在 Wikipedia. 上找到说明

例如,要选择具有特定应用程序标识符 (AID) 的智能卡上的应用程序,您可以执行以下 APDU 命令。结果仅表示正常 (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();

关于android - 从 NFC 标签读取数据 (IsoDep),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16815007/

相关文章:

android - 每个通知都有自己的包含唯一数据的 PendingIntent

java - Android 上带有 JMRTD 的外部 RFID 阅读器

java - 将事件添加到日历时设置事件的颜色

android - 如何在 Android 上使用 CameraX 获取可用分辨率?

android - 如何从弹出窗口获取输入

android - 如何直接打开图库应用挑选图片

java - Android listView右滑时子位置错误

android - 有哪些替代方法可以启动我的应用程序?

ios - iOS 中的 ADPU 服务

android - NFC 广播接收器问题