Android NFC:智能海报NDEF记录,带有连接的“URI”和“文本”内容

时间:2014-03-12 16:19:48

标签: android nfc ndef

我开发了一个多功能NFC应用程序,它能够读取和写入不同类型的标签和不同类型的格式,包括外部类型,RTD文本和RTD URI。但是,解析和读取" TNF_WELL_KNOWN"智能海报内容。更具体地说,从我遇到的问题开始,我使用了众所周知的" NFC TagWriter" Android上的app创建简单的联系内容。该联系人包含姓名,例如" Police"和电话号码,例如" 911"。当尝试使用另一个名为" NFC TagInfo"的流行应用程序阅读相同的内容时,我能够成功阅读智能海报,准确显示它应该显示的内容:

WELL-KNOWN:urn:nfc:wkt:Sp(智能海报)

  1. WELL-KNOWN:urn:nfc:wkt:U(URI) 标识符:0x05(" tel:") " 911"
  2. WELL-KNOWN:urn:nfc:wkt:U(Text) 编码:UTF-8 语言:en "警察"
  3. 另一方面,我无法实现同样的目标。以下是我想出的解码上述内容的代码:

    首先,我提取NDEF消息及其相应的NDEF记录:

     // Use NdefMessage[] getNdefMessages(Intent) method to extract NDEF Message(s)
    
     NdefMessage[] ndefMessages = getNdefMessages(intent);
     for(int i = 0; i < ndefMessages.length; i++) {
    
        ndefRecords = ndefMessages[i].getRecords();
    
        for (int j = 0; j < ndefRecords.length; j++) { 
    
            // NDEF Record parsing snippet comes here!
            if (ndefRecords[j].getTnf() == NdefRecord.TNF_WELL_KNOWN) {
    
               // If TNF indicates a "Well-known" type,
               // determine the type using "Type" field  
    
               if (Arrays.equals(ndefRecords[j].getType(),  NdefRecord.RTD_SMART_POSTER)) {
    
                   // First try to decode the content
                   payload = new String(ndefRecords[j].getPayload(), 1, ndefRecords[j].getPayload().length - 1, Charset.forName("UTF-8"));
                   Log.i(TAG, "Content: " + payload);
    
                   // Second try to decode the content
                   Log.i(TAG, "Content: " + ndefRecords[j].toUri());
               }
             }
           }
        }
    

    查看Logcat输出时,第一个Log.i打印:

    U911Q   TenPolice
    

    第二次打印时:

    tel:911
    

    在我看来,NFC TagWriter应用程序创建了一个嵌套的NDEF记录,其中一个URI类型和一个Text类型连接在一起。我试图找出如何成功解码此内容。第一次尝试删除有效负载头并解码NDEF记录有效负载的剩余部分。显然,第一部分包含&#34; tel:911&#34;内容和第二部分包含&#34;警察&#34;,其中&#34; en&#34;表示语言。第二次尝试使用NDEFRecord类&#39; toUri()helper方法,根据API文档能够提取RTD URI。我想知道为了提取所有嵌套记录,我们可以解码一个,将其转换为byte []数组并从有效载荷中删除,这将被重新迭代以进行另一次解码。虽然,这种方法看起来效率很低。所以,我想知道其他专家建议如何处理这个问题。

    [更新]以下是为感兴趣的人撰写智能海报NDEF记录的简短片段:

    NdefRecord uriNdefRecord = NdefRecord.createUri(Uri.parse((String) o[0])); //RTD_URI
    NdefRecord textNdefRecord = createTextRecord((String) o[1], Locale.US, true); //RTD_TEXT
    NdefRecord[] recs = new NdefRecord[]{uriNdefRecord, textNdefRecord};
    NdefMessage smartPosterpContentMessage = new NdefMessage(recs);
    byte[] bytes = smartPosterpContentMessage.toByteArray();
    NdefRecord newRec = new NdefRecord((short) 0x01, NdefRecord.RTD_SMART_POSTER, null, bytes);
    ndefMessageWriter(new NdefMessage(newRec));   
    

    在上面的代码片段中,&#34; ndefMessageWriter&#34;使用线程与标签通信并将内容写入标签。

1 个答案:

答案 0 :(得分:2)

正确地发现,智能海报记录包含文本记录和URI记录作为其有效负载。所以你要做的就是获取这些记录是为了解码智能海报记录的有效载荷(顺便说一句。如果你已经用Google搜索了“智能海报记录”,你会快速提出智能海报记录类型定义规范,抓住它{{ 3}})。

您已经发现SP记录包含NDEF消息,因此您将把记录的有效负载解码为NDEF消息:

NdefMessage spContentMsg = new NdefMessage(spRecord.getPayload());

现在你有一条NDEF消息,根据规范,它至少包含一条URI记录和一些其他可选记录(例如每种语言的一条描述性文本记录):

NdefRecord[] spContentRecs = spContentMsg.getRecords();
for (NdefRecord rec : spContentRecs) {
    if (rec.getTnf() == NdefRecord.TNF_WELL_KNOWN) {
       if (Arrays.equals(rec.getType(),  NdefRecord.RTD_URI)) {
           // do something
       } else if (Arrays.equals(rec.getType(),  NdefRecord.RTD_TEXT)) {
           // do something
       }
     }
   }
}

顺便说一句,大多数here的规范编写得很好且易于遵循(特别是各种NDEF和RTD相关规范)。