吃辣条的大妖怪
吃辣条的大妖怪
  • 发布:2019-03-13 17:19
  • 更新:2019-06-06 18:02
  • 阅读:948

uniapp 实现 NFC标签读取 和 写入

分类:uni-app

参考文章链接:
NFC读取卡片ID
磊子文章

uniapp 开发,找了很久没找到相关的NFC读写的代码;解决相关问题也用了些时间,希望文章有用;

最开始没有找到uniapp中的,NFC贴上手机后对应的响应事件;
有发帖提问怎么解决;
链接:uniapp怎么监听h5+的event事件http://ask.dcloud.net.cn/question/66505
在uniapp中:封装在 onShow 和onHide

代码基本同之前磊子提供的一样,全部放在methods 里面;
listenNFCStatus()
在onLoad的时候调用;
读写是在onShow的时候调用;

下面这段

nfcAdapter.disableForegroundDispatch(main);  

打算放在onHide但是出现三方脚本错误的报错;
没法解决;就没放 = =;

但是单独的读没有任何影响,这是我写了读出数据会有个消息弹框,响应NFC并读取数据的方法是在onShow里面的;

手机息屏重新打开,扔会出发onShow,自动又调用了一次读取数据,所以遇到bug就是NFC的响应事件和手机息屏事件冲突;

暂时加了个计数器 count ,第一次进入的时候不调用读取;并且在hide和show加了时间戳,通过onHide 和 onShow响应的时间差,来判断是否触发读取事件;

如果有小伙伴知道怎么弄求分享

附上整体js代码,部分自己的function已删除;

    var NfcAdapter;  
    var NdefRecord;  
    var NdefMessage;  
    var waiting  
    var readyRead = false;  
    var nfcAdapter,main , pendingIntent,intentFiltersArray,techListsArray, IntentFilter  

    export default {  
        data() {  
            return {  
                currentNFCInfo: [], //NFC 读取消息;  
                bannerShow: false,  
                remark:"",  
                message: "",  
                count:0,  
                timestampHide:"",  
                timestampShow:""  
            };  
        },  
        methods: {  
            listenNFCStatus() {  
                try {  
                    console.log('Init NFC...');  
                    main = plus.android.runtimeMainActivity();  
                    var Intent = plus.android.importClass('android.content.Intent');  
                    var Activity = plus.android.importClass('android.app.Activity');  
                    var PendingIntent = plus.android.importClass('android.app.PendingIntent');  
                    IntentFilter = plus.android.importClass('android.content.IntentFilter');  
                    NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');  
                    nfcAdapter = NfcAdapter.getDefaultAdapter(main);  
                    var intent = new Intent(main, main.getClass());  
                    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
                    pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);  
                    var ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");  
                    ndef.addDataType("*/*");  
                    intentFiltersArray = [ndef];  
                    techListsArray = [  
                        ["android.nfc.tech.IsoDep"],  
                        ["android.nfc.tech.NfcA"],  
                        ["android.nfc.tech.NfcB"],  
                        ["android.nfc.tech.NfcF"],  
                        ["android.nfc.tech.Ndef"],  
                        ["android.nfc.tech.NfcV"],  
                        ["android.nfc.tech.NdefFormatable"],  
                        ["android.nfc.tech.MifareClassic"],  
                        ["android.nfc.tech.MifareUltralight"]  
                    ];  

                } catch (e) {  
                    console.error(e);  
                }  
            },  
            handle_nfc_data() {  

                NdefRecord = plus.android.importClass("android.nfc.NdefRecord");  
                NdefMessage = plus.android.importClass("android.nfc.NdefMessage");  
                // main = plus.android.runtimeMainActivity();  
                var intent = main.getIntent();  

                console.log("action type:" + intent.getAction());  
                if ("android.nfc.action.TECH_DISCOVERED" == intent.getAction()) {  
                    if (readyRead) {  
                        this.__read(intent);  
                        readyRead = false;  
                    }  
                } else {  
                    // waiting.close();  
                    console.log("nfc读取失败")  
                }  
            },  
            __read(intent) {  
                try {  
                    var content = "";  
                    waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");  
                    waiting.setTitle('请勿移开标签\n正在读取数据...');  
                    var tag = plus.android.importClass("android.nfc.Tag");  
                    waiting.close();  
                    var Parcelable = plus.android.importClass("android.os.Parcelable");  
                    // var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");  
                    var rawmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);  

                    if (rawmsgs != null && rawmsgs.length > 0) {  
                        waiting.close();  
                        // console.log(JSON.stringify(rawmsgs[0]));  
                        var records = rawmsgs[0].getRecords();  
                        var result = records[0].getPayload();  
                        // console.log(result)  
                        if (result != null) {  
                            var s = plus.android.newObject("java.lang.String", result);  
                            console.log(s);  
                            this.currentNFCInfo = s;  
                        } else {  
                            this.currentNFCInfo = "";  
                        }  
                    } else {  
                        console.log("NFC获取失败");  
                        uni.showToast({  
                            title: "NFC获取失败.",  
                            icon: "none"  
                        });  
                    }  

                } catch (e) {  
                    console.log(e);  
                    console.log("NFC获取失败,丢出异常");  
                    waiting.close();  
                    uni.showToast({  
                        title: "NFC获取失败,丢出异常.",  
                        icon: "none"  
                    });  
                    //TODO handle the exception  
                }  
            },  
            readData() {  
                readyRead = true;  
            //  waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");  
                setTimeout(this.handle_nfc_data, 1000);  
            }  
        },  
        onLoad: function(option) {  
            this.listenNFCStatus()  
        },  
        onShow: function(){  
            console.log('page Show');  
            this.timestampShow = (new Date()).getTime();  
            console.log(this.timestampShow)  
            var TimeScale =  this.timestampShow - this.timestampHide;  
            console.log(TimeScale);  
                        nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);  
            if(this.count++ == 0){  
                // this.listenNFCStatus()  
                return false;  
            }else if(TimeScale > 400){  
                return false;  
            }else{  
                this.readData();  
            }  
        },  
        onHide:function(){  
            console.log("onHide");  
            this.timestampHide = (new Date()).getTime();  
            console.log(this.timestampHide);  
        }  
    }  

写入分开写了,也是一样的写法

            __write(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 Ndef = plus.android.importClass('android.nfc.tech.Ndef');  
                    var NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');  
                    var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
                    var ndef = Ndef.get(tag);  
                    if (ndef != null) {  
                        var size = message.toByteArray().length;  
                        console.log("size=" + size);  
                        ndef.connect();  
                        if (!ndef.isWritable()) {  
                            console.log("tag不允许写入");  
                            waiting.close();  
                            uni.showToast({  
                                title: "tag不允许写入.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        if (ndef.getMaxSize() < size) {  
                            console.log("文件大小超出容量");  
                            waiting.close();  
                            uni.showToast({  
                                title: "文件大小超出容量.",  
                                icon: "none"  
                            });  
                            return;  
                        }  
                        // console.log('写入数据:' + JSON.stringify(message) + ' __TYPE__: ' + JSON.stringify(message.__TYPE__));  
                        console.log("message:" + message)  
                        ndef.writeNdefMessage(message);  

                        waiting.close();  
                        console.log("写入数据成功.");  
                        uni.showToast({  
                            title: "写入数据成功.",  
                            icon: "none"  
                        });  
                        this.writeCode = "XJD:" + this.detailObj.code;  
                        this.updateCode(); //数据写入成功后,数据关联成功;  
                        return;  
                    } else {  
                        var format = NdefFormatable.get(tag);  
                        if (format != null) {  
                            try {  
                                format.connect();  
                                format.format(message);  
                                console.log("格式化tag并且写入message")  
                                waiting.close();  
                                return;  
                            } catch (e) {  
                                console.log("格式化tag失败.");  
                                waiting.close();  
                                uni.showToast({  
                                    title: "格式化tag失败.",  
                                    icon: "none"  
                                });  
                                return;  
                            }  
                        } else {  
                            console.log("Tag不支持NDEF");  
                            uni.showToast({  
                                title: "Tag不支持NDEF",  
                                icon: "none"  
                            });  
                            waiting.close();  
                            return;  
                        }  
                    }  
                } catch (e) {  
                    console.log("error=" + e);  
                    waiting.close();  
                    console.log('写入失败');  
                }  
            },  
            writeData() {  
                readyWriteData = true;  
                // waiting = plus.nativeUI.showWaiting("请将NFC标签靠近!");  
                setTimeout(this.handle_nfc_data, 1000);  
            },  

最近新增了,可读写nfcv格式的标签
http://ask.dcloud.net.cn/article/36108

有其他小伙伴解决了或者有更好的方式可以多多交流

3 关注 分享
DCloud_heavensoft woeoio@qq.com yahf4057@163.com

要回复文章请先登录注册

吃个魔方压压惊

吃个魔方压压惊

回复 DCloud_heavensoft:
nice,终于可以使用newintent了
2019-06-06 18:02
393149280@qq.com

393149280@qq.com

action type:android.nfc.action.TECH_DISCOVERED
2019-05-16 16:13
393149280@qq.com

393149280@qq.com

大兄弟,我怎么报错啊
2019-05-16 10:33
DCloud_heavensoft

DCloud_heavensoft

HBuilderX 1.9,开启新编译模式,新增了这个api:plus.globalEvent.addEventListener('netchange', function(){});

详见:[https://uniapp.dcloud.io/use-html5plus](https://uniapp.dcloud.io/use-html5plus)
2019-04-18 07:02