读取NFC标签时出现奇怪的字符 [英] Strange character when reading NFC tag

查看:97
本文介绍了读取NFC标签时出现奇怪的字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Android读取NFC标签.我是养蜂人,当我接近他们时,这是为了识别我的蜂箱.我在这里搜索过,但是在阅读标签时仍然遇到问题.我想阅读文本,但是当阅读时,有一个方形字符,并且在所需文本之前显示的字符类似十".

I am trying to read an NFC tag using Android. I'm a beekeeper and this is to ID my hives when I approach them. I have searched here but I am still having issues reading the tag. I want to read the text, but when it reads, there is a square-like character and characters displayed like " Ten" before the desired text.

这是我正在使用的代码.我知道有效负载字节必须正确,并且我尝试更改它们,但无济于事.

Here is the code I'm using. I know that the payload bytes have to be correct and I have tried changing them but to no avail.

private static NdefMessage getTestMessage() {
    byte[] mimeBytes = "application/com.android.cts.verifier.nfc"
            .getBytes(Charset.forName("US-ASCII"));
    byte[] id = new byte[] {1, 3, 3, 7};
    byte[] payload = "CTS Verifier NDEF Push Tag".getBytes(Charset.forName("US-ASCII"));
    return new NdefMessage(new NdefRecord[] {
            new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, id, payload)
    });
}

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

    mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, null, null);
    mNfcAdapter.setNdefPushMessageCallback(this, this);
}

// sending message
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
    return getTestMessage();
}


private NdefMessage[] getNdefMessages(Intent intent) {
    Parcelable[] rawMessages = intent
      .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    if (rawMessages != null) {
        NdefMessage[] messages = new NdefMessage[rawMessages.length];
        for (int i = 0; i < messages.length; i++) {
            messages[i] = (NdefMessage) rawMessages[i];
        }
        return messages;
    } else {
        return null;
    }
}

static String displayByteArray(byte[] bytes) {
    String res="";
    StringBuilder builder = new StringBuilder().append("");
    for (int i = 0; i < bytes.length; i++) {
        res+=(char)bytes[i];
    }
    return res;

}

// displaying message
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    NdefMessage[] messages = getNdefMessages(intent);
    edtUser.setText(displayByteArray(messages[0].toByteArray()));

    Toast.makeText(this, "NFC tag entered", Toast.LENGTH_LONG).show();
}

推荐答案

由于您尝试将整个原始NDEF记录显示为文本字符串(使用某种奇数解码方法),因此在显示消息时,您会得到其他奇数字符:

You are getting odd additional characters when displaying the message since you try to display the whole raw NDEF record as text string (using some odd decoding method):

NdefMessage[] messages = getNdefMessages(intent);
edtUser.setText(displayByteArray(messages[0].toByteArray()));

这有几个问题.首先,您通常希望使用与编写文本相同的编码对文本进行解码.例如,如果您使用

There are several problems with this. First of all, you would typically want to decode the text using the same encoding that you used to write the text. For instance, if you used

String text = "...";
byte[] bytes = text.getBytes(Charset.forName("US-ASCII"));

要获得给定文本字符串的US-ASCII编码字节数组,您还希望使用相同的US-ASCII编码再次将字节转换为文本字符串:

to get a byte array in US-ASCII encoding for a given text string, you would also want to use that same US-ASCII encoding to translate the bytes into a text string again:

byte[] bytes = ...;
String text = new String(bytes, "US-ASCII");

第二,您将整个NDEF消息解释为文本字符串.但是,您存储在标签上的文本通常仅包含在NDEF记录的有效载荷之内.在您的情况下,前缀十"表示您使用的语言指示为"en"的NFC论坛文本记录(类型名称"T")(对于英语).因此,您需要在NDEF消息中搜索文本"记录:

Second, you are interpreting the whole NDEF message as a text string. However, the text that you stored on the tag is typically only contained inside the payload of an NDEF record. In your case, the prefix "Ten" suggests that you used an NFC Forum Text record (type name "T") with the language indication "en" (for English). You would, therefore, want to search the NDEF message for the Text record:

for (NdefRecord r : messages[0].getRecords()) {
    if (r.getTnf() == NdefRecord.TNF_WELL_KNOWN) {
        if (Arrays.equals(r.getType(), NdefRecord.RTD_TEXT)) {

找到文本记录后,就可以解码其文本有效负载.有效负载由状态字节,语言字段和实际文本组成:

Once you found the Text record, you can decode its text payload. The payload consists of a status byte, a language field and the actual text:

            byte[] payloadBytes = ndefRecord.getPayload();
            boolean isUTF8 = (payloadBytes[0] & 0x080) == 0;  //status byte: bit 7 indicates encoding (0 = UTF-8, 1 = UTF-16)
            int languageLength = payloadBytes[0] & 0x03F;     //status byte: bits 5..0 indicate length of language code
            int textLength = payloadBytes.length - 1 - languageLength;
            String languageCode = new String(payloadBytes, 1, languageLength, "US-ASCII");
            String payloadText = new String(payloadBytes, 1 + languageLength, textLength, isUTF8 ? "UTF-8" : "UTF-16");

            edtUser.setText(payloadText);
        }
    }
}

这篇关于读取NFC标签时出现奇怪的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆