uniapp app nfc读取IC卡数据

这篇具有很好参考价值的文章主要介绍了uniapp app nfc读取IC卡数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

读取芯片卡ID

/*
 * desc:封装NFC功能,实现安卓设备对NFC标签读取卡号,支持android5.0及以上版本,仅支持 android 平台 
 */
// 包路径
const package_NdefRecord = 'android.nfc.NdefRecord';
const package_NdefMessage = 'android.nfc.NdefMessage';
const package_TECH_DISCOVERED = 'android.nfc.action.TECH_DISCOVERED';
const package_Intent = 'android.content.Intent';
const package_Activity = 'android.app.Activity';
const package_PendingIntent = 'android.app.PendingIntent';
const package_IntentFilter = 'android.content.IntentFilter';
const package_NfcAdapter = 'android.nfc.NfcAdapter';
const package_Ndef = 'android.nfc.tech.Ndef';
const package_NdefFormatable = 'android.nfc.tech.NdefFormatable';
const package_Parcelable = 'android.os.Parcelable';
const package_String = 'java.lang.String';

let NfcAdapter;
let NdefRecord;
let NdefMessage;
let techListsArray = [
	['android.nfc.tech.IsoDep'],
	['android.nfc.tech.NfcA'],
	['android.nfc.tech.NfcB'],
	['android.nfc.tech.NfcF'],
	['android.nfc.tech.Nfcf'],
	['android.nfc.tech.NfcV'],
	['android.nfc.tech.NdefFormatable'],
	['android.nfc.tech.MifareClassi'],
	['android.nfc.tech.MifareUltralight']
];
let readyRead = false;

export default {
	nfcGetId: function(obj) {
		let that = this;
		try {
			let main = plus.android.runtimeMainActivity();
			let Intent = plus.android.importClass('android.content.Intent');
			let Activity = plus.android.importClass('android.app.Activity');
			let PendingIntent = plus.android.importClass('android.app.PendingIntent');
			let IntentFilter = plus.android.importClass('android.content.IntentFilter');
			NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
			let nfcAdapter = NfcAdapter.getDefaultAdapter(main);

			if (nfcAdapter == null) {
				uni.showToast({
					title: '设备不支持NFC!',
					icon: 'none'
				})
				return;
			}

			if (!nfcAdapter.isEnabled()) {
				uni.showToast({
					title: '请在系统设置中先启用NFC功能!',
					icon: 'none'
				});
				return;
			} 
			
			let intent = new Intent(main, main.getClass());
			intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			let pendingIntent = PendingIntent.getActivity(main, 0, intent, 0);
			let ndef = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
			ndef.addDataType("*/*");
			let intentFiltersArray = [ndef];

			plus.globalEvent.addEventListener('newintent', function() {
				console.log('newintent running');
				// 监听 NFC
				setTimeout(function() {
					NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
					NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
					let main = plus.android.runtimeMainActivity();
					let intent = main.getIntent();
					//let that = this;
					
					console.log("action type:" + intent.getAction());
					
					if (package_TECH_DISCOVERED == intent.getAction()) {
						if (readyRead) {
							uni.showToast({
								title: '请勿移开标签正在读取数据',
								icon: 'none'
							});
							//let that = this;
							// NFC id
							let bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
							let nfc_id = that.byteArrayToHexString(bytesId);
							console.log('nfc_id:'+ nfc_id);
							obj.success(nfc_id);
							readyRead = false;
						}
					}	
				}, 1000);
			});
			plus.globalEvent.addEventListener('pause', function(e) {
				console.log('pause running');
				if (nfcAdapter) {
					//关闭前台调度系统
					//恢复默认状态
					nfcAdapter.disableForegroundDispatch(main);
				}
			});
			plus.globalEvent.addEventListener('resume', function(e) {
				console.log('resume running');
				if (nfcAdapter) {
					//开启前台调度系统
					nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
				}
			});
			nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
			
			// 监听事件,触发条件
			readyRead = true;
			uni.showToast({
				title: '请将NFC标签靠近!',
				icon: 'none'
			});
						
		} catch (e) {
			console.error(e);
			obj.fail(e);
		} finally{
			obj.complete();
		}
	},

	byteArrayToHexString: function(inarray) {
		let i, j, inn;
		let hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
		let 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;
	},

}

先勾选权限
uniapp app nfc读取IC卡数据,uni-app,前端,android,交互
判断当前设备是否支持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文件文章来源地址https://www.toymoban.com/news/detail-605074.html

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

到了这里,关于uniapp app nfc读取IC卡数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Uniapp uni-app学习与快速上手

    个人开源uni-app开源项目地址:准备中 在线展示项目地址:准备中 什么是uni-app uni,读 you ni ,是统一的意思。 Dcloud即数字天堂(北京)网络技术有限公司是W3C成员及HTML5中国产业联盟发起单位,致力于推进HTML5发展构建,HTML5生态。 2012年,DCloud开始研发小程序技术,优化webvie

    2024年02月09日
    浏览(58)
  • 前端-vscode中开发uni-app

    node -v npm install @vue/ cli@4.5.15 -g 指定版本号:4.5.15 在自己电脑目录下创建项目: demo02是自己项目名字 在D/AllCode/vs_vue2_uniapp目录下执行一下命令: vue create -p dcloudio/uni-preset-vue demo02 要想在vscode执行npm命令 我们打开pages.json和manifest.json,发现会报红,这是因为在json中是不能写注

    2024年01月18日
    浏览(65)
  • uni-app 获取android相册

    在uni-app中提供的封装好的api中没有提供获取手机相册的能力,只能打开相册后由用户选择其中的照片,而插件库中提供的获取相册的插件都是收费的,这里为大家分享一个可以自己获取android相册的代码段:

    2024年02月11日
    浏览(46)
  • UNI-APP 人脸识别分析及实现(前端)

    实现流程: 1、打开摄像头——自动读取照片——传输给后端——后端交由第三发或自主开发来识别——返回结果(相识度比) 2、打开摄像头——自动读取视频——传输给后端——后端通过解析视频,截取图片交由第三发或自主开发来识别——返回结果(相识度比) 通过分

    2023年04月08日
    浏览(43)
  • uni-app如何区分 app、h5、小程序代码; uni-app如何判断是android、ios、小程序

    uniapp是DCloud公司于2012年开始研发的能够一次代码开发,生成H5、小程序(微信、支付宝、百度、华为等)、APP等应用的技术的统称,开发工具是HBuilderX,功能非常强大,由此引申出许多技术社区与生态环境。 使用HBuilderX开发Uniapp程序的项目,用它生成多端应用,由于兼容各种

    2024年02月11日
    浏览(69)
  • 【UniApp】-uni-app-项目实战页面布局(苹果计算器)

    经过前面的文章介绍,基本上 UniApp 的内容就介绍完毕了 那么从本文开始,我们就开始进行一个项目的实战 这次做的项目是苹果计算器,这个项目的难度不是很大,但是也不是很简单,适合练手 打开 HBuilderX,点击左上角 文件 - 新建 - 项目 : 项目创建完毕之后,首先来分析

    2024年02月04日
    浏览(63)
  • 【uni-app教程】四、UniAPP 路由配置及页面跳转

    uni-app 页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router。 uni-app 有两种页面路由跳转

    2024年01月16日
    浏览(73)
  • uni-app小程序实现音频播放,uniapp播放录音,uniapp简单实现播放录音

    复制到.vue文件即可预览效果 问题 :开发者工具中.onTimeUpdate方法可能会失效! 官方参考:https://uniapp.dcloud.net.cn/api/media/audio-context.html# 其他博客参考:https://blog.csdn.net/weixin_45328705/article/details/114091301 录音实现参考 :https://blog.csdn.net/weixin_43992507/article/details/129857780

    2024年02月12日
    浏览(73)
  • #Uniapp:uni-app中vue2生命周期--11个

    uni-app中vue2生命周期 生命周期钩子 描述 H5 App端 小程序 说明 beforeCreate 在实例初始化之后被调用 详情 √ √ √ created 在实例创建完成后被立即调用 详情 √ √ √ beforeMount 在挂载开始之前被调用 详情 √ √ √ mounted 挂载到实例上去之后调用 详情 注意:此处并不能确定子组件

    2024年02月02日
    浏览(48)
  • uni-app之android原生插件开发

    一 插件简介 1.1 当HBuilderX中提供的能力无法满足App功能需求,需要通过使用Andorid/iOS原生开发实现时,可使用App离线SDK开发原生插件来扩展原生能力。 1.2 插件类型有两种,Module模式和Component模式 Module模式:能力扩展,无嵌入窗体的UI控件。大部分插件都是属于此类,比如调

    2024年02月07日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包