为什么 Android NFC 阅读器添加了"#39;s"en"在消息之前? [英] Why Android NFC reader add's "en" before the message?

查看:54
本文介绍了为什么 Android NFC 阅读器添加了"#39;s"en"在消息之前?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在测试 NFC,但我认为它正在格式化中遇到问题..

Hey guys im testing NFC and i have an issue with i think it is formating..

我在标签中添加了一个字符串值,其中包含要编写的应用程序.

I added a string value in the tag with an app to write.

当我用同一个商店应用程序扫描它时,它显示正常...

when i scan it with that same store app it shows ok...

当我用我的应用程序扫描时,它会在应用程序中显示正确的名称,但在消息前添加了一个en"..

when i scan with my app it shows the correct name in the app but adds a "en" before the message..

和一个空格..所以如果我在标签中添加一个名称然后扫描并获取一个API,它会显示404,因为有一个en和空格..

and a white space.. so if i add a name in the tag then scan and get a API it shows 404 cause there is an en and white space..

http://myapisite.com/API/getdevice.php?id= enTagString

http://myapisite.com/API/getdevice.php?id= enTagString

在 = 空格之前,然后在我放置的 id 或什至名称之前的 en..

before the = space and then en before the id or even name i put..

我尝试了几种方法..

public class MainActivity extends Activity {
    // list of NFC technologies detected:
    private final String[][] techList = new String[][]{
            new String[]{
                    NfcA.class.getName (),
                    NfcB.class.getName (),
                    NfcF.class.getName (),
                    NfcV.class.getName (),
                    IsoDep.class.getName (),
                    MifareClassic.class.getName (),
                    MifareUltralight.class.getName (), Ndef.class.getName ()
            }
    };
    private TextView mTextView;
    private ImageView mImageView;
    private String ID, machineName, MachineImg, MachinePart, level;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_main);
        mImageView = findViewById (R.id.imageView);
        mTextView = findViewById (R.id.textView_explanation);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater ().inflate (R.menu.menu, menu);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume ();
        PendingIntent pendingIntent = PendingIntent.getActivity (this, 0, new Intent (this, getClass ()).addFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        // creating intent receiver for NFC events:
        IntentFilter filter = new IntentFilter ();
        filter.addAction (NfcAdapter.ACTION_TAG_DISCOVERED);
        filter.addAction (NfcAdapter.ACTION_NDEF_DISCOVERED);
        filter.addAction (NfcAdapter.ACTION_TECH_DISCOVERED);
        // enabling foreground dispatch for getting intent from NFC event:
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
        nfcAdapter.enableForegroundDispatch (this, pendingIntent, new IntentFilter[]{filter}, this.techList);
    }

    @Override
    protected void onPause() {
        super.onPause ();
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
        nfcAdapter.disableForegroundDispatch (this);
    }

    void parseNdefMessage(Intent intent) {
        Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra (
                NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
        String text = new String (ndefMessage.getRecords ()[0].getPayload ());
        Log.d (TAG, "PAYLOAD MESS" + text);
        ID = text;
        getApiInfos ();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        parseNdefMessage (intent);
        if (intent.getAction ().equals (NfcAdapter.ACTION_TAG_DISCOVERED)) {
            mTextView.setText ("NFC Tag\n" + ByteArrayToHexString (intent.getByteArrayExtra (NfcAdapter.EXTRA_ID)));

            Parcelable tagN = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
            if (tagN != null) {
                NdefMessage[] msgs;
                byte[] empty = new byte[0];
                byte[] id = intent.getByteArrayExtra (NfcAdapter.EXTRA_ID);
                byte[] payload = dumpTagData (tagN).getBytes ();
                NdefRecord record = new NdefRecord (NdefRecord.TNF_UNKNOWN, empty, id, payload);
                NdefMessage msg = new NdefMessage (new NdefRecord[]{record});
                msgs = new NdefMessage[]{msg};
                Log.d (TAG, msgs[0].toString ());

            } else {
                Log.d (TAG, "Parcelable NULL");
            }
            Parcelable[] messages1 = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (messages1 != null) {
                Log.d (TAG, "Found " + messages1.length + " NDEF messages");
                for (int i = 0; i < messages1.length; ++i) {
                    Log.d (TAG, "Found M " + messages1[i].toString ());
                }
            } else {
                Log.d (TAG, "Not EXTRA_NDEF_MESSAGES");
            }

            Tag tag = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
            Ndef ndef = Ndef.get (tag);
            if (ndef != null) {
                Parcelable[] messages = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
                if (messages != null) {
                    Log.d (TAG, "Found " + messages.length + " NDEF messages");
                }
            } else {
                Log.d (TAG, "Write to an unformatted tag not implemented");
            }
        }
    }

    private String dumpTagData(Parcelable p) {
        StringBuilder sb = new StringBuilder ();
        Tag tag = (Tag) p;
        byte[] id = tag.getId ();
        sb.append ("Tag ID (hex): ").append (getHex (id)).append ("\n");
        sb.append ("Tag ID (dec): ").append (getDec (id)).append ("\n");
        sb.append ("ID (reversed): ").append (getReversed (id)).append ("\n");
        String prefix = "android.nfc.tech.";
        sb.append ("Technologies: ");
        for (String tech : tag.getTechList ()) {
            sb.append (tech.substring (prefix.length ()));
            sb.append (", ");
        }
        sb.delete (sb.length () - 2, sb.length ());
        for (String tech : tag.getTechList ()) {
            if (tech.equals (MifareClassic.class.getName ())) {
                sb.append ('\n');
                MifareClassic mifareTag = MifareClassic.get (tag);
                String type = "Unknown";
                switch (mifareTag.getType ()) {
                    case MifareClassic.TYPE_CLASSIC:
                        type = "Classic";
                        break;
                    case MifareClassic.TYPE_PLUS:
                        type = "Plus";
                        break;
                    case MifareClassic.TYPE_PRO:
                        type = "Pro";
                        break;
                }
                sb.append ("Mifare Classic type: ");
                sb.append (type);
                sb.append ('\n');

                sb.append ("Mifare size: ");
                sb.append (mifareTag.getSize () + " bytes");
                sb.append ('\n');

                sb.append ("Mifare sectors: ");
                sb.append (mifareTag.getSectorCount ());
                sb.append ('\n');

                sb.append ("Mifare blocks: ");
                sb.append (mifareTag.getBlockCount ());
            }

            if (tech.equals (MifareUltralight.class.getName ())) {
                sb.append ('\n');
                MifareUltralight mifareUlTag = MifareUltralight.get (tag);
                String type = "Unknown";
                switch (mifareUlTag.getType ()) {
                    case MifareUltralight.TYPE_ULTRALIGHT:
                        type = "Ultralight";
                        break;
                    case MifareUltralight.TYPE_ULTRALIGHT_C:
                        type = "Ultralight C";
                        break;
                }
                sb.append ("Mifare Ultralight type: ");
                sb.append (type);
            }
        }

        DateFormat TIME_FORMAT = SimpleDateFormat.getDateTimeInstance ();
        Date now = new Date ();

        mTextView.setText (TIME_FORMAT.format (now) + '\n' + sb.toString ());
        return sb.toString ();
    }


    private String getHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder ();
        for (int i = bytes.length - 1; i >= 0; --i) {
            int b = bytes[i] & 0xff;
            if (b < 0x10)
                sb.append ('0');
            sb.append (Integer.toHexString (b));
            if (i > 0) {
                sb.append (" ");
            }
        }
        return sb.toString ();
    }

    private long getDec(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = 0; i < bytes.length; ++i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    private long getReversed(byte[] bytes) {
        long result = 0;
        long factor = 1;
        for (int i = bytes.length - 1; i >= 0; --i) {
            long value = bytes[i] & 0xffl;
            result += value * factor;
            factor *= 256l;
        }
        return result;
    }

    private String ByteArrayToHexString(byte[] inarray) {
        int i, j, in;
        String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
        String out = "";

        for (j = 0; j < inarray.length; ++j) {
            in = (int) inarray[j] & 0xff;
            i = (in >> 4) & 0x0f;
            out += hex[i];
            i = in & 0x0f;
            out += hex[i];
        }
        Log.d ("ByteArrayToHexString", String.format ("%0" + (inarray.length * 2) + "X", new BigInteger (1, inarray)));
        return out;
    }
enter code here

推荐答案

这很可能是因为应用程序编写将其存储为WELL_KNOWN"类型的文本/纯文本

Most likely this is because the App writing is storing it as a "WELL_KNOWN" type of text/plain

NFC 文本格式的规范可以在 NFCForum-TS-RTD_Text_1.0.pdf.

The specs for NFC Text format can be found at NFCForum-TS-RTD_Text_1.0.pdf.

payload 中的额外字符如下:

The extra characters in the payload are as below:

  • 语言长度(1 字节)+ 语言(n 字节)+ 文本

所以空间实际上是语言的不可打印大小.

So the space is the actually a non printable size of the language.

en"定义文本为英文.

The "en" is defining that the text is English.

https://developer.android.com/reference/android/nfc/NdefRecord#getPayload()返回一个字节数组.

所以下面应该可以修剪它(测试),因为似乎没有很好的辅助方法来解码它,只能创建这种格式.

So below should work to trim it (tested) as there don't seem to be nice helper methods to decode it, only create this format.

// Create Test Record
NdefRecord record = NdefRecord.createTextRecord("en", "Hello");

//Get Bytes of payload
// byte[] payload = ndefMessage.getRecords ()[0].getPayload ();
// Get Bytes of test NDEF Record
byte[] payload = record.getPayload ();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1 , payload.length);
// Convert to Text
String text = new String(textArray);

更新:由于问题中给出的代码有点混乱,你做你不需要做的事情,也不要做你需要做的事情(例如,你已经要求从不会做的卡发送数据在它们中有 NDef 数据,然后你解析 Ndef 数据而不检查是否有一些数据要解析)

UPDATE: As the code given in the question is a bit of a mess and you do things you don't need to do and don't do things you do need to do (e.g. you have asked to be sent data from cards that won't have NDef data in them and then you parse for Ndef data without checking there is some data to parse)

我简化了代码只是为了读取文本 NDEF 记录(注意未测试,但基于我过去读取 NDEF 数据的方式,我现在使用更好的方法来读取更可靠的卡片,尤其是如果你想也可以写入卡片)

I've simplified the code just to read a text NDEF record (Note not tested, but based on how I used to read NDEF data, I now use a better method to read cards that is more reliable especially if you want to write to cards as well)

public class MainActivity extends Activity {
    private TextView mTextView;
    private ImageView mImageView;
    private String ID, machineName, MachineImg, MachinePart, level;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mImageView = findViewById(R.id.imageView);
        mTextView = findViewById(R.id.textView_explanation);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        // creating intent receiver for NFC events:
        IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        // enabling foreground dispatch for getting intent from NFC event:
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, new IntentFilter[]{filter}, null);
    }

    @Override
    protected void onPause() {
        super.onPause();
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        nfcAdapter.disableForegroundDispatch(this);
    }

    void parseNdefMessage(Intent intent) {
        Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra(
                NfcAdapter.EXTRA_NDEF_MESSAGES);
        // Test if there is actually a NDef message passed via the Intent
        if (ndefMessageArray != null) {
            NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
            //Get Bytes of payload
            byte[] payload = ndefMessage.getRecords()[0].getPayload();
            // Read First Byte and then trim off the right length
            byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1, payload.length);
            // Convert to Text
            String text = new String(textArray);
            ID = text;
            getApiInfos();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {

        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
            parseNdefMessage(intent);
        }
    }
}

这篇关于为什么 Android NFC 阅读器添加了&amp;quot;#39;s&amp;quot;en&amp;quot;在消息之前?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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