uniapp app nfc读取IC卡数据

news2024/12/24 9:02:58

先勾选权限
在这里插入图片描述
判断当前设备是否支持NFC以及是否打开了NFC功能

var main = plus.android.runtimeMainActivity();
var NfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
var _nfcAdapter = NfcAdapter.getDefaultAdapter(main);
console.log('NFC',_nfcAdapter)
if (_nfcAdapter == null) {
  console.log("本手机不支持NFC")
} else if (_nfcAdapter.isEnabled() == false) {
  console.log("NFC功能未打开")
} else {
  console.log('okokokok')
}

页面使用

import nfc from "@/common/nfc.js" //nfc代码放js文件里
onLoad(){
	nfc.Into()
},
onReady() {
	console.log('onready')
	let that = this
	nfc.data.callback = function(data){
		console.log('getId', data)
		uni.$emit('refreshNFC', { refresh: true , data: data});
		uni.navigateBack()
	}
},
onShow(){
	nfc.readData()
},
onHide() {
	nfc.nfcclose()
},

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: 13, //0号扇区
		initVal:'FFFFFFFFFFFF',
		keyValA: '837210987622', //扇区密码
		keyValB: '12BBADDAEA11',
		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();
		console.log(intent.getAction())
		if (intent.getAction() == "android.nfc.action.TECH_DISCOVERED") {
			// console.log('222222')
			clearInterval(this.data.IntervalId);
			// intent.setAction('android.intent.action.MAIN')
			if (this.data.status === 'read') {
				console.log('开始读取信息')
				this._readData(intent);
			} else {
				// console.log('开始写入数据')
				this._WriteData(intent);
			}
		}
	},
	// 16进制转10进制
	hex2int:function(val) {
	    var len = val.length;
		var callVal ="";
	    for (var i = 0; i < len; i++) {
	      callVal += val[i];
	    }
	    
	    return parseInt(callVal,16);
	},
	// byte转16进制
	Bytes2Str: function(arrBytes) {
		var str = "";
		for (var i = 0; i < arrBytes.length; i++) {
			var tmp;
			var num = arrBytes[i];
			if (num < 0) {
				//此处填坑,当byte因为符合位导致数值为负时候,需要对数据进行处理
				tmp = (255 + num + 1).toString(16);
			} else {
				tmp = num.toString(16);
			}
			if (tmp.length == 1) {
				tmp = "0" + tmp;
			}
			if (i > 0) {
				str += ":" + tmp;
			} else {
				str += tmp;
			}
		}
		return str;
	},
	//读取设备
	_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 cmdBytesA = this.HexStringToByteArray(this.data.keyValA);
			var cmdBytesB = this.HexStringToByteArray(this.data.keyValB);
			var initBytes = this.HexStringToByteArray(this.data.initVal)
			var auth = false;
			if (invoke(mfc, "authenticateSectorWithKeyA", parseInt(this.data.sector), cmdBytesA)) {
				console.log("aaaaaaaaaaaaaaaaaaaaaa")
				console.log(invoke(mfc, "authenticateSectorWithKeyA", parseInt(this.data.sector), cmdBytesA))
				auth = true;
				// return;
			} else if(invoke(mfc, "authenticateSectorWithKeyB", parseInt(this.data.sector), cmdBytesB))  {
				console.log("bbbbbbbbbbbb")
				auth = true;
				// return;
			}
			// console.log(invoke(mfc, "authenticateSectorWithKeyA", parseInt(this.data.sector), cmdBytesA))
			console.log(8888888888)
			console.log(invoke(mfc, "authenticateSectorWithKey", parseInt(this.data.sector), initBytes))
			if(
			!invoke(mfc, "authenticateSectorWithKeyA", parseInt(this.data.sector), cmdBytesA) &&
			!invoke(mfc, "authenticateSectorWithKeyB", parseInt(this.data.sector), cmdBytesB)){
				uni.hideLoading();
				uni.showModal({
					content: "未发卡",
					showCancel: false
				});
				return;
			}
			
			if (!auth) {
				uni.hideLoading();
				uni.showModal({
					content: "请靠近一点",
					showCancel: false
				});
				return;
			}


			console.log('666666')
			console.log(auth)
			var data = mfc.readBlock(52);
			var str = this.Bytes2Str(data);
			var arr = str.split(":");
			var callValue = this.hex2int(arr.splice(0,5));  //车用截取 前4位  液化与工业 截取前5位
			console.log("值:" + str)
			this.data.callback(callValue);
			mfc.close();
			// this.nfcclose();
			// uni.showModal({
			//     content: "扇区读取成功",
			//     showCancel: false
			// });
		} 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";
		this.data.IntervalId = setInterval(()=>{
			this.handle_nfc_data();
		}, 1000);
	},
}

export default Nfc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/783333.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

43:Three.js - 中

一、相机 相机&#xff0c;类似于眼睛&#xff0c;用于在3D舞台中&#xff0c;放置在不同的位置&#xff0c;实现通过不同的角度观察物体。 查看 Three.js 的文档&#xff0c;可以看到 Camera 是一个抽象类&#xff0c;一般不直接使用&#xff0c;其他类型的 Camera 实现了这个…

循环链表的实现

循环链表简介 简单来说&#xff0c;单链表像一个小巷&#xff0c;无论怎么样最终都能从一端走到另一端&#xff0c;循环链表则像一个有传送门的小巷&#xff0c;因为循环链表当你以为你走到结尾的时候&#xff0c;其实你又回到了开头。循环链表和非循环链表其实创建的过程以及…

RS485自由转PROFINET网关连接扫码枪

捷米JM-RS485/232-PN(RS485转Profinet)将具有RS485/232接口、自由通信协议接口的设备与PROFINET相连&#xff0c;作为PROFINET现场总线系统的一个设备。 捷米JM-RS485/232-PN集成了一个2端口交换机。受支持的以太网服务&#xff1a;ping、arp、SNMP和LLDP。端口诊断。禁用端口…

MySQL HA:如何将“删库跑路”的损失降到最低

对于任何一个企业来说&#xff0c;数据安全的重要性是不言而喻的。我在开篇词中也曾经强调过&#xff0c;凡是涉及到数据的问题&#xff0c;都是损失惨重的大问题。 能够影响数据安全的事件&#xff0c;都是极小概率的事件&#xff0c;比如说&#xff1a;数据库宕机、磁盘损坏…

服务器用友数据库中了locked勒索病毒后怎么解锁数据恢复

随着信息技术的迅速发展&#xff0c;服务器成为现代企业中不可或缺的重要设备。然而&#xff0c;由于网络安全风险的存在&#xff0c;服务器在日常运作中可能遭受各种威胁&#xff0c;包括恶意软件和勒索病毒攻击。近日&#xff0c;我们收到很多企业的求助&#xff0c;企业的用…

influxdb数据转移到clickhouse,顺便记录一些influxdb的常用命令

其实应该先写个influxdb初探的&#xff0c;但是当时没有时间时间都用来养龟养鱼了还有摸鱼了。 本篇先讲我是如何将influxdb数据转移到clickhouse的&#xff0c;再记录influxdb的一些常用命令 1、influxdb数据转移到clickhouse influxdb不管是查询还是导出的数据格式都很麻烦…

快手内推(2024校招,社招)

校招 校招可以直接投递&#xff0c;如果想投递指定部门或岗位的可以私聊我。可以帮看简历和面试状态&#xff0c;加快推进。 内推码&#xff1a;vlxMTFNBS 专属内推链接&#xff1a;https://campus.kuaishou.cn/#/campus/jobs?codevlxMTFNBS 社招 社招内推私聊&#xff0c;可…

Ubuntu 安装 Gif 工具 -- Peek

Ubuntu 安装 Gif 工具 – Peek 一直想找一个 Ubuntu 下的录制 Gif 的工具&#xff0c;后来测试发现 Peek 非常舒服&#xff0c;推荐使用&#xff5e;&#xff5e;&#xff5e; 一、添加Peek的ppa源 sudo add-apt-repository ppa:peek-developers/stable二、更新源 sudo apt…

春秋云境:CVE-2022-24124(Casdoor api get-oraganizations SQL注入)

目录 一、题目&#xff1a; 二、进入题目&#xff1a; 1.官方POC&#xff1a; 2.SQL的分析&#xff1a; 2.1 POC: 2.2 burp爆破字符&#xff1a; 2.3 大佬的POC&#xff08;SQL查询&#xff09;&#xff1a; 一、题目&#xff1a; 题目介绍&#xff1a; Casdoor是开源的…

23.7.20 杭电暑期多校2部分题解

1001 - Alice Game 题目大意 有一个长度为 n n n 的怪物序列&#xff08; n n n 可能为 0 0 0&#xff09;&#xff0c;给定一个 k k k&#xff0c;轮到某人回合时会有两种操作&#xff1a; 选择一个连续的序列&#xff0c;它的长度小于等于 k k k&#xff0c;将其全部删…

【转载】elasticsearch 倒排索引原理

由于整型数字 integer 可以被高效压缩的特质&#xff0c;integer 是最适合放在 postings list 作为文档的唯一标识的&#xff0c;ES 会对这些存入的文档进行处理&#xff0c;转化成一个唯一的整型 id&#xff08;这个id是document的id&#xff09;。 再说下这个 id 的范围&…

VS Code 使用 autoDocstring 插件快速生成 python 函数的文档字符串

VS Code 使用 autoDocstring 插件快速生成 python 函数的文档字符串 支持的文档类型用法扩展设置此扩展提供以下设置&#xff1a;设置方式自定义文档字符串模板附加部分 支持的文档类型 googlesphinxnumpydocBlockrone-line-sphinxpep257 用法 光标必须位于定义正下方的行上…

【strapi系列】strapi在postman中如何调试public和认证用户Authorization的接口

文章目录 一、public用户的调试二、认证用户的调试1、新建一个用户&#xff0c;用于获得token2、调用获取token的接口来获得token3、请求时携带token调用权限接口 三、参考链接 一、public用户的调试 对于public用户&#xff0c;如果是get请求&#xff0c;即使不在postman&…

【git学习】

版本控制 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。 实现跨区域多人协同开发追踪和记载一个或者多个文件…

wordpress如何实现显示文章和分类ID?

可以直接将下面的代码添加到当前主题的 functions.php 文件即可 <?php /*** WordPress后台的文章、分类&#xff0c;媒体&#xff0c;页面&#xff0c;评论,链接等所有信息中显示ID并将ID设置为第一列*/ // 添加一个新的列 ID function ssid_column($columns) {//将ID设置…

一个企业级的文件上传组件应该是什么样的

目录 1.最简单的文件上传 2.拖拽粘贴样式优化 3.断点续传秒传进度条 文件切片 计算hash 断点续传秒传(前端) 断点续传秒传(后端) 进度条 4.抽样hash和webWorker 抽样hash(md5) webWorker 时间切片 5.文件类型判断 通过文件头判断文件类型 6.异步并发数控制(重要…

Linux部署程序之glibc兼容性问题

Linux部署程序之glibc兼容性问题 在部署程序的时候&#xff0c;一般会遇到glibc不兼容的问题&#xff0c;现象如下&#xff1a; /lib64/libstdc.so.6: version GLIBCXX_3.4.21’ not found在此之前先要了解一下 gcc/glibc/libc/libstdc 是什么东东。 gcc/glibc/libc/libstdc…

PHP变量和常量(基础语法)

文章目录 PHP变量和常量&#xff08;基础语法&#xff09;简介变量常量 PHP中的变量变量基础全局变量超全局变量静态变量 PHP常量基础总结 PHP变量和常量&#xff08;基础语法&#xff09; 简介 变量和常量是编程语言中不可或缺的元素&#xff0c;它们类似于盒子&#xff0c;…

06 QT自定义信号和槽

案例&#xff1a;创建教师类和学生类&#xff0c;教师发出自定义hungry信号&#xff0c;学生响应信号&#xff0c;执行treat函数。 创建老师和学生类&#xff08;由于老师和学生不是控件&#xff0c;所以选择QObject作为基类&#xff09; 1&#xff1a;老师发送自定义信号&…

「深度学习之优化算法」(十七)灰狼算法

1. 灰狼算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读)   灰狼算法(Grey Wolf Algorithm)是受灰狼群体捕猎行为启发而提出的算法。算法提出于2013年,仍是一个较新的算法。目前为止(2020)与之相关的论文也比较多,但多为算法的应用,应该仍有研究和改进的余…