uni-app调用NFC读写加密扇区功能。

1.先新建一个nfc.js文件。

let Context = plus.android.importClass("android.content.Context");
let NfcManager = plus.android.importClass("android.nfc.NfcManager");
let NfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
let Settings= plus.android.importClass("android.provider.Settings");
let Intent = plus.android.importClass("android.content.Intent");
let Parcelable = plus.android.importClass("android.os.Parcelable");
let PendingIntent = plus.android.importClass('android.app.PendingIntent');
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
let NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
let NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
let Tag = plus.android.importClass("android.nfc.Tag");
let MifareClassic = plus.android.importClass("android.nfc.tech.MifareClassic");
let invoke = plus.android.invoke;

const Nfc={
    //所需要的数据
    data:{
        sector:0,//0号扇区
        keyVal:'f1e2d3c4b5a6',//扇区密码
        status:'read',//当前操作方式:是读卡 还是 写卡
        WriteData:'',//当status为write时生效。需要写入的数字。长度不能超过32位。只能为数字
        block:1,//当status为write时生效。需要写入0号扇区的几号块
        keyType:'A',//验证方式
        nfcAdapter:null,
        ICUID:'',//卡片ID
        main:null,
        intent:null,
        IntervalId:null,
        callback:null,//回调事件
        techListsArray:[
            ["android.nfc.tech.IsoDep"],
            ["android.nfc.tech.NfcA"],
            ["android.nfc.tech.NfcB"],
            ["android.nfc.tech.NfcF"],
            ["android.nfc.tech.NfcV"],
            ["android.nfc.tech.Ndef"],
            ["android.nfc.tech.NdefFormatable"],
            ["android.nfc.tech.MifareClassic"],
            ["android.nfc.tech.MifareUltralight"]
        ]
    },
    //初始化
    Into:function (){
        this.data.main=plus.android.runtimeMainActivity();
        var nfchManager = this.data.main.getSystemService(Context.NFC_SERVICE);
        var nfcAdapter = nfchManager.getDefaultAdapter();
        if(!nfcAdapter.isEnabled()){
            this.data.intent= new Intent(Settings.ACTION_NFC_SETTINGS);
            this.data.main.startActivity(this.data.intent); 
        }
        var intent = new Intent(this.data.main, this.data.main.getClass());
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        var pendingIntent = PendingIntent.getActivity(this.data.main, 0, intent, 0);
        var ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
        ndef.addDataType("*/*");
        var intentFiltersArray = [ndef];
        nfcAdapter.enableForegroundDispatch(this.data.main, pendingIntent, intentFiltersArray, this.data.techListsArray);
        this.data.nfcAdapter=nfcAdapter;
    },
    //取消操作
    nfcclose:function(){
        if(this.data.nfcAdapter)
            this.data.nfcAdapter.disableForegroundDispatch(this.data.main);
        this.data.nfcAdapter=null;
        clearInterval(this.data.IntervalId);
    },
    //轮询获取当前NFC设备触发的事件
    handle_nfc_data:function(){
        console.log('轮训中')
        var intent = this.data.main.getIntent();
        if(intent.getAction()=="android.nfc.action.TECH_DISCOVERED"){
            clearInterval(this.data.IntervalId);
            if(this.data.status==='read')
            {
                console.log('开始读取信息')
              this._readData(intent);    
            }
            else{
                console.log('开始写入数据')
                this._WriteData(intent);    
            }
            
        }
    },
    //读取设备
    _readData:function(intent){
        
        setTimeout(function () {
            uni.hideLoading();
        }, 2000);
        
        var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        var techList = tag.getTechList();
        var bisMfc=false;
        for(var i=0;i<techList.length;i++){
            if(techList[i].indexOf('MifareClassic')>=0){
                bisMfc=true;
                break;
            }
        }
        if(!bisMfc){
            uni.hideLoading();
            uni.showModal({
                content: "卡片类型错误",
                showCancel: false
            });
            return;
        }
        var mfc=MifareClassic.get(tag);
        if(!mfc){
            uni.hideLoading();
            uni.showModal({
                content: "卡片获取错误",
                showCancel: false
            });
            return;
        }
        mfc.setTimeout(3000);
        if(!mfc.isConnected()){
            try{
                invoke(mfc,'connect'); 
            }catch(e){
                uni.hideLoading();
                uni.showModal({
                    content: "卡片连接错误",
                    showCancel: false
                });
                
                return;
            }
        }
        
        try{
            this.data.ICUID=this.ByteArrayToHexString(tag.getId());
            
            var cmdBytes=this.HexStringToByteArray(this.data.keyVal);
            var auth=false;
            if(this.data.keyType=="A"){
                auth=invoke(mfc,"authenticateSectorWithKeyA",parseInt(this.data.sector),cmdBytes);
            }else{
                auth=invoke(mfc,"authenticateSectorWithKeyB",parseInt(this.data.sector),cmdBytes);
            }
            if(!auth){
                uni.hideLoading();
                uni.showModal({
                    content: "请靠近一点",
                    showCancel: false
                });
                return;
            }
            
            var arr=[]
            for (var i = 0; i < 4; i++) {
                var data = mfc.readBlock(i);
                console.log('当前'+i+"号块:读取的内容:"+data)
                arr.push(this.ByteArrayToHexString(data))
            }
            mfc.close();
            uni.showModal({
                content: "扇区读取成功",
                showCancel: false
            });
            
            //this.nfcclose();
            this.data.callback(arr)
            
        }catch(e){
            console.error(e); 
        }finally{
            mfc.close();
        }
    },
    //写入数据
    _WriteData:function(intent){
        uni.hideLoading();
        uni.showLoading({
            title: '正在写入中.请勿移开'
        });
        
        var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        var techList = tag.getTechList();
        var bisMfc=false;
        for(var i=0;i<techList.length;i++){
            if(techList[i].indexOf('MifareClassic')>=0){
                bisMfc=true;
                break;
            }
        }
        if(!bisMfc){
            uni.hideLoading();
            uni.showModal({
                content: "卡片类型错误",
                showCancel: false
            });
            return;
        }
        var mfc=MifareClassic.get(tag);
        if(!mfc){
            uni.hideLoading();
            uni.showModal({
                content: "卡片获取错误",
                showCancel: false
            });
            return;
        }
        mfc.setTimeout(3000);
        if(!mfc.isConnected()){
            try{
                invoke(mfc,'connect'); 
            }catch(e){
                uni.hideLoading();
                uni.showModal({
                    content: "卡片连接错误",
                    showCancel: false
                });
                
                return;
            }
        }
        
        try{
            this.data.ICUID=this.ByteArrayToHexString(tag.getId());
            console.log(this.data.keyVal)
            var cmdBytes=this.HexStringToByteArray(this.data.keyVal);
            var auth=false;
            if(this.data.keyType=="A"){
                auth=invoke(mfc,"authenticateSectorWithKeyA",parseInt(this.data.sector),cmdBytes);
            }else{
                auth=invoke(mfc,"authenticateSectorWithKeyB",parseInt(this.data.sector),cmdBytes);
            }
            if(!auth){
                uni.hideLoading();
                uni.showModal({
                    content: "请靠近一点",
                    showCancel: false
                });
                return;
            }
            
            //开始写入指定块
            //mfc.writeBlock(this.data.block,this.HexStringToByteArray("11111111100000000000000000000000"));
            mfc.writeBlock(this.data.block,this.HexStringToByteArray(this.data.WriteData));
            //验证是否写入成功
             var data = mfc.readBlock(this.data.block);
             console.log(this.ByteArrayToHexString(data))
             console.log(this.data.WriteData)
             if(this.ByteArrayToHexString(data)===this.data.WriteData)
             {
                 uni.hideLoading();
                 mfc.close();
                 uni.showModal({
                     content: "写入完成",
                     showCancel: false
                 });
                 this.data.callback({status:1,msg:'写入成功'})
             }else{
                console.log('写入失败')
                 this.data.callback({status:0,msg:'写入失败'})
             }
            
            
        }catch(e){
            console.error(e); 
        }finally{
            mfc.close();
        }
    },
    ByteArrayToHexString:function(inarray) {
        var i, j, inn;
        var hex = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
        var out = '';
        for(j = 0; j<inarray.length; ++j) { 
            inn = inarray[j] & 0xff;
            i = (inn >>> 4) & 0x0f;
            out += hex[i]; 
            i = inn & 0x0f;
            out += hex[i];
        }
        return out;
    },
    HexStringToByteArray:function(instr) {
        var hexA = new Array();
        var pos = 0;
        var len = instr.length/2;
        for(var i=0; i<len; i++)
        {
            var s = instr.substr(pos, 2);
            var v = parseInt(s, 16);
            if(v>=128)
                v=v-256;
            hexA.push(v);
            pos += 2;
        }
        return hexA;
    },
    //对外开放的读取事件
    readData:function(){
        //输入请靠近设备
        uni.showLoading({
            title: '请靠近设备'
        });
        this.data.status="read"
        var that=this
        this.data.IntervalId = setInterval(function(){
            that.handle_nfc_data();
        },1000);
    },
    //对外开放的写入事件
    //传一个需要写入的数据
    writeData:function(value){
        //输入请靠近设备
        this.data.status="write"
        uni.showLoading({
            title: '请靠近设备'
        });
        if(value.length>32)
        {
            uni.showModal({
                content: "写入数据长度不能超过32位",
                showCancel: false
            });
        }
        for(var i=value.length;i<32;i++)
        {
            value+='0';
        }
        console.log(value);
        console.log(value.length)
        
        this.data.WriteData=value
        var that=this
        this.data.IntervalId = setInterval(function(){
            that.handle_nfc_data();
        },1000);
    }
}

export default Nfc

2.调用Demo

<template>
    <view class="uni-common-mt">
        <button type="primary" @click="readcard">读卡操作</button>
 
 
        <view class="uni-form-item uni-column">
            <view class="title">输入需要写入的内容</view>
            <input type="number" class="uni-input" v-model="value" placeholder="请输入写入的内容" />
        </view>
 
        <button type="primary" @click="writecard">写卡操作</button>
 
        <view>
            <text>{{arr}}</text>
        </view>
    </view>
</template>
 
<script>
    import nfc from '@/components/nfc/Nfc.js'
    export default {
        data() {
            return {
                value: '888999',
                arr:[]
            }
        },
        onLoad: function() {
            console.log('当页面启动后')
            //初始化
            nfc.Into();
        },
        methods: {
            update(e) {
                console(e) //e是子组件传递过来的值,就是子组件的index
            },
            dataAction() {
                this.$refs.main.childMethod()
                //这是页面触发子组件的方法
                //main是组件的ref
            },
            readcard: function() {
                console.log('调用读卡功能')
                var that=this
                nfc.readData();
                nfc.data.callback = function(e) {
                    console.log(e)
                    that.arr=e;
                }
            },
            writecard: function() {
                console.log('调用写卡功能')
 
                nfc.writeData(this.value);
                nfc.data.callback = function(e) {
                    console.log(e)
                }
            }
        }
    }
</script>
 
<style>
</style>

3.别忘了开启nfc权限
在这里插入图片描述
4.还有封装好的插件 https://ext.dcloud.net.cn/search?q=nfc

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值