吃辣条的大妖怪
吃辣条的大妖怪
  • 发布:2019-07-04 17:44
  • 更新:2022-06-22 10:53
  • 阅读:5137

uniapp NFC可读写nfcv格式的nfc标签

分类:uni-app

需求:

在实现了可读写nfc(ndef)标签后,需要兼容另一个标签格式nfcv。

uniapp下nfc如果没有读到参考 uniapp 实现 NFC标签读取 和 写入

读:

java参考代码

private void readNfcv(Tag tag) {  
        System.out.println("进入readNfcv方法");  
        NfcV tech = NfcV.get(tag);  
        if (tech != null) {  
            try {  
                tech.connect();  
                if (tech.isConnected()) {  
                    byte[] tagUid = tag.getId();  
                    System.out.println("ceshi00000:"+tagUid);  
                    // store tag UID for use in addressed commands  
                    //读第一个block  
                    byte[] read = new byte[]{  
                            (byte) 0x22,  // FLAGS  
                            (byte) 0x23,  // 20-READ_SINGLE_BLOCK,23-所有块  
                            0, 0, 0, 0, 0, 0, 0, 0,  
                            0, 0  
                    };  
                    System.out.println("ceshi:"+read);  
                    System.arraycopy(tagUid, 0, read, 2, tagUid.length);  // paste tag UID into command  
                    byte[] res = tech.transceive(read);  
                    System.out.println("2222222:"+res);  
                    if (res != null) {  
                        System.out.println("标记:"+ Arrays.toString(res));  
                        //nfcContent.append("NfcV: " + new String(res, Charset.forName("utf-8")));  
                        if(res[1] == 'H'&& res[2] =='J' && res[3] == 'I'){  
                            int blockAddress = 1;  
                            int blocknum = res[4];  
                            byte[] cmd = new byte[]{  
                                    (byte) 0x22,  // FLAGS  
                                    (byte) 0x23,  // 20-READ_SINGLE_BLOCK,23-所有块  
                                    0, 0, 0, 0, 0, 0, 0, 0,  
                                    (byte) (blockAddress & 0x0ff), (byte) (blocknum - 1 & 0x0ff)  
                            };  
                            System.arraycopy(tagUid, 0, cmd, 2, tagUid.length);  // paste tag UID into command  
                            byte[] response = tech.transceive(cmd);  
                            System.out.println("主要数据"+Arrays.toString(response));  
                            if (response != null) {  
                                nfcContent.append("NfcV: " + new String(response, Charset.forName("utf-8")));  
                            }  
                        }  
                    }  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }finally {  
                try {  
                    tech.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }

js实现代码:

        readNfcV(intent) {  
            var NfcV = plus.android.importClass('android.nfc.tech.NfcV');  
            var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
            // console.log(tag);  
            console.log(NfcV.get(tag));  
            var tech = NfcV.get(tag);  
            if (tech != null) {  
                try {  
                    tech.connect();  
                    console.log(tech.isConnected());  
                    if (tech.isConnected()) {  
                        console.log('卡片字节数组ID:' + tag.getId());  
                        var tagUid = tag.getId();  
                        var buffer = [];  
                        buffer[0] = 0x22;  
                        buffer[1] = 0x23;  
                        for (var i in tagUid) {  
                            // console.log(tagUid[i]);  
                            buffer.push(tagUid[i]);  
                        }  
                        buffer[10] = 0;  
                        buffer[11] = 0;  
                        console.log(buffer);  
                        var res = tech.transceive(buffer);  
                        if (res != null) {  
                            console.log('标记:' + res);  
                            if (String.fromCharCode(res[1]) == 'H' && String.fromCharCode(res[2]) == 'J' && String.fromCharCode(res[3]) == 'I') {  
                                var blockAddress = 1;  
                                var blocknum = res[4];  
                                var cmd = [];  
                                cmd[0] = 0x22;  
                                cmd[1] = 0x23;  
                                for (var i in tagUid) {  
                                    // console.log(tagUid[i]);  
                                    cmd.push(tagUid[i]);  
                                }  
                                cmd[10] = blockAddress & 0x0ff;  
                                cmd[11] = (blocknum - 1) & 0x0ff;  
                                console.log(cmd);  
                                var response = tech.transceive(cmd);  
                                var str = ""  
                                for(var j in response){  
                                    // console.log(typeof response[j])  
                                    str +=this.bytesToString(response[j]);  
                                }  
                                console.log(str)  

                            }  
                        }  

                    }  
                } catch (e) {  
                    //TODO handle the exception  
                }  
            }else{  
                this.readNfc(intent)  
            }  
        },

写:

JAVA参考代码

 public void writeNfcV(View view) {  
        System.out.println("进入writeNfcV方法");  
        NfcV nfcV = null;  
        Intent intent = getIntent();  
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
        if (tag == null) {  
            nfcContent.append("未检测到NFC标签!");  
            return;  
        }  
        try {  
            nfcV = NfcV.get(tag);  
            nfcV.connect();  
            System.out.println("最大字节数:"+nfcV.getMaxTransceiveLength());  
            byte[] ID = nfcV.getTag().getId();  
            byte[] cmd = new byte[15];  
            cmd[0] = (byte) 0x22;  
            cmd[1] = (byte) 0x21;  
            System.arraycopy(ID, 0, cmd, 2, ID.length); // UID  
            byte[] input = nfcWrite.getText().toString().getBytes();  
            int count = (input.length+3)/4;//存储block数(用户输入)  
            System.out.println("count:"+count);  
            byte[] data = new byte[(count+1)*4];  
            System.out.println("data000:"+Arrays.toString(data));  
            byte[] mark = new byte[4];  
            mark[0] = 'H';  
            mark[1] = 'J';  
            mark[2] = 'I';  
            mark[3] = (byte) count;  
            System.out.println("MARK01:"+Arrays.toString(mark));  
            System.arraycopy(mark,0,data,0,4);  
            System.out.println("DATA01:"+Arrays.toString(data));  
            System.arraycopy(input,0,data,4,input.length);  
            System.out.println("DATA02:"+Arrays.toString(data));  
            for (int i = 0; i < count+1; i++) {  
                cmd[10] = (byte)(i & 0x0ff);  
                System.arraycopy(data, i*4, cmd, 11, 4);  
                byte[] rsp = nfcV.transceive(cmd);  
                if(rsp[0] == 0x00 && i==count) {  
                    Toast.makeText(this, "已成功写入数据!", Toast.LENGTH_LONG).show();  
                }  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally {  
            try {  
                if(nfcV != null) {  
                    nfcV.close();  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }

JS实现代码

__writeNfcV(intent) {  
                try {  
                    waiting = plus.nativeUI.showWaiting('请将NFC标签靠近!');  
                    waiting.setTitle('请勿移开标签\n正在写入...');  
                    // var text = document.getElementById('text').value;  
                    console.log('text=' + this.writeCode);  
                    var textBytes = plus.android.invoke(this.writeCode, 'getBytes');  
                    var textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, plus.android.invoke('text/plain', 'getBytes'), plus.android  
                        .invoke('', 'getBytes'), textBytes);  
                    var message = new NdefMessage([textRecord]);  
                    var NfcV = plus.android.importClass('android.nfc.tech.NfcV');  
                    // var NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');  
                    var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
                    var nfcv = NfcV.get(tag);  
                    console.log('标签格式:' + nfcv);  
                    var bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);  
                    console.log('bytesId:' + bytesId);  
                    // console.log(nfcv.getTag().getId())  
                    if (nfcv != null) {  
                        nfcv.connect();  
                        var size = nfcv.getMaxTransceiveLength();  
                        this.writeCode = '123456';//编辑内容  
                        var strVal = this.writeCode;  
                        console.log("zijie:" + this.stringToByte(strVal))  
                        var strValByte = this.stringToByte(strVal);  
                        console.log(strValByte.length)  
                        console.log('最大字节数:' + size);  
                        var cmd = [];  
                        cmd[0] = 0x22;  
                        cmd[1] = 0x21;  
                        for (var i in bytesId) {  
                            // console.log(tagUid[i]);  
                            cmd.push(bytesId[i]);  
                        }  
                        console.log(cmd);  
                        var count = parseInt(strValByte.length + 3)/4 ;//存block数  
                        console.log("count:"+count);  
                        var datav = new Array((count+1)*4);  
                        console.log("datav:"+datav)  
                        // var mark = [];  
                        // mark[0]="72"; //H  
                        // mark[1] = "74";//J  
                        // mark[2] = "73";//I  
                        // mark[3]=count;  
                        datav[0] = 72;  
                        datav[1] = 74;  
                        datav[2] = 73;  
                        datav[3] = count;  
                        // console.log("datav01:"+datav)  
                        for(var j=0;j<strValByte.length;j++){  
                            // console.log(strValByte[j]);  
                            datav[4+j] = strValByte[j]  
                        }  
                        console.log("datav02:"+datav);  
                        for(var i = 0;i<count+1;i++){  
                            cmd[10] = i&0x0ff;  
                            for(var s=0;s<4;s++){  
                                cmd[11+s] = datav[4*i+s];  
                            }  
                            // cmd[11+i]=datav[i*4+i]  

                            console.log("cmd22:"+cmd);  
                            var rsp = nfcv.transceive(cmd);  
                            console.log(rsp[0])  
                            if(rsp[0] == 0x00&& i == count){  
                                console.log('写入数据成功.');  
                                uni.showToast({  
                                    title: '写入数据成功.',  
                                    icon: 'none'  
                                });  

                            }  
                        }  

                        waiting.close();  
                        return;  

                    } else {  
                        console.log("未检测到NFCV标签");  
                        waiting.close();  
                        this.__write(intent);  
                        return;  
                    }  
                } catch (e) {  
                    console.log('error=' + e);  
                    waiting.close();  
                    uni.showToast({  
                        title: 'NFC标签写入失败,请重新贴近手机',  
                        icon: 'none'  
                    });  
                }  
            },  
stringToByte(str) {   
                var bytes = new Array();  
                var len, c;  
                len = str.length;  
                for (var i = 0; i < len; i++) {  
                    c = str.charCodeAt(i);  
                    if (c >= 0x010000 && c <= 0x10FFFF) {  
                        bytes.push(((c >> 18) & 0x07) | 0xF0);  
                        bytes.push(((c >> 12) & 0x3F) | 0x80);  
                        bytes.push(((c >> 6) & 0x3F) | 0x80);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else if (c >= 0x000800 && c <= 0x00FFFF) {  
                        bytes.push(((c >> 12) & 0x0F) | 0xE0);  
                        bytes.push(((c >> 6) & 0x3F) | 0x80);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else if (c >= 0x000080 && c <= 0x0007FF) {  
                        bytes.push(((c >> 6) & 0x1F) | 0xC0);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else {  
                        bytes.push(c & 0xFF);  
                    }  
                }  
                return bytes;  

            },

ps:
写的时候被自己蠢到了,java btye[]浪费了写时间,结果在最简单的w3c文档中看到byte在js中属于number。

4 关注 分享
w***@qq.com 8***@qq.com 星云6 Descartes

要回复文章请先登录注册

1***@qq.com

1***@qq.com

请问nfc怎么写入url
2022-06-22 10:53
睡到自然醒呀

睡到自然醒呀

请问为啥我进入主目录文件 1PAY.SYS.DDF01 报错6D00;请帮忙看下指令
```
var test = '00a404000e315041592e5359532e4444463031';

isoDep.transceive(this.Str2Bytes(test));

// 十六进制转字节数组
Str2Bytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var hexA = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
},
```
2022-03-24 15:32
睡到自然醒呀

睡到自然醒呀

回复 星云6 :
请问为啥我进入主目录文件 1PAY.SYS.DDF01 报错6D00;请帮忙看下指令
var test = '00a404000e315041592e5359532e4444463031';
isoDep.transceive(this.Str2Bytes(test));

// 十六进制转字节数组
Str2Bytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var hexA = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
},
2022-03-24 15:22
大海的凡夫俗子

大海的凡夫俗子

js代码 tag.getId()报错,提示 tag.getId is not a function,是什么原因呢?
2021-12-08 15:51
星云6

星云6

感谢大佬,实践可用,我用的卡是IsoDep格式也可以用这种写法,'android.nfc.tech.NfcV'改为'android.nfc.tech.IsoDep'即可
2021-10-28 17:51