uniapp は読み取りおよび書き込み操作のために Android ネイティブ NFC を呼び出します

  • 読み取り操作
<template>
	<view>
		<uni-popup ref="popup" @change="change">
			<view class="popup">
				<view class="">请刷卡读取数据</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	var NfcAdapter;
	var MifareClassic;
	
	export default {
		components: {
			uniPopup
		},
		data() {
			return {
				formData: {
					bind_code: '',
					tagid: '',
					time: null,
					show: false,

				}
			}
		},
		methods: {
			open() {
				//开启阴影遮罩前检查NFC状态
				var main = plus.android.runtimeMainActivity();
				NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
				var _nfcAdapter = NfcAdapter.getDefaultAdapter(main);
				if (_nfcAdapter == null) {
					uni.showToast({
						icon: "error",
						title: "该设备不支持NFC",
						duration: 5000
					})
				} else if (_nfcAdapter.isEnabled() == false) {
					uni.showToast({
						icon: "error",
						title: "NFC功能未打开",
						duration: 5000
					})
				} else {
					this.$refs.popup.open("top");
					//初始化ncf 并开启监听
					this.NFCInit();
				}

			},
			change(e, s) {
				if (!e.show) {
					//销毁监听事件
					plus.globalEvent.removeEventListener("newintent", false);
				}
			},
			// nfc入口
			NFCInit() {
				try {
					
					var main = plus.android.runtimeMainActivity();
					//console.log(main);
					var Intent = plus.android.importClass('android.content.Intent');
					// console.log(Intent);
					var Activity = plus.android.importClass('android.app.Activity');
					//console.log(Activity);
					var PendingIntent = plus.android.importClass('android.app.PendingIntent');
					// console.log(PendingIntent);
					var IntentFilter = plus.android.importClass('android.content.IntentFilter');
					var NdefRecord = plus.android.importClass('android.nfc.NdefRecord')
					var NdefMessage = plus.android.importClass('android.nfc.NdefMessage')
					MifareClassic = plus.android.importClass("android.nfc.tech.MifareClassic");

					NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
					
					var _nfcAdapter = NfcAdapter.getDefaultAdapter(main);


					var ndef = new IntentFilter('android.nfc.action.NDEF_DISCOVERED'); //NfcAdapter.ACTION_NDEF_DISCOVERED

					var tag = new IntentFilter('android.nfc.action.TAG_DISCOVERED'); //NfcAdapter.ACTION_TECH_DISCOVERED
					console.log(tag);
					var tech = new IntentFilter('android.nfc.action.TECH_DISCOVERED');

					var intentFiltersArray = [ndef, tag, tech];

					var techListsArray = [
						['android.nfc.tech.Ndef'],
						['android.nfc.tech.IsoDep'],
						['android.nfc.tech.NfcA'],
						['android.nfc.tech.NfcB'],
						['android.nfc.tech.NfcF'],
						['android.nfc.tech.Nfcf'],
						['android.nfc.tech.Nfef'], 
						['android.nfc.tech.Ndef'], 
						['android.nfc.tech.NfcV'],
						['android.nfc.tech.NdefFormatable'],
						['android.nfc.tech.MifareClassi'],
						['android.nfc.tech.MifareUltralight']
					];
					var _intent = new Intent(main, main.getClass());
					// console.log(_intent);
					_intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

					var pendingIntent = PendingIntent.getActivity(main, 0, _intent, 0);
					var that = this;
					//监听贴卡到手机事件 
					plus.globalEvent.addEventListener('newintent', e => {
						//获取ic卡数据
						that.NFCReadUID()
						//销毁监听事件
						plus.globalEvent.removeEventListener("newintent", false);
					});
					if (_nfcAdapter == null) {} else if (_nfcAdapter.isEnabled() == false) {} else {
						_nfcAdapter.enableForegroundDispatch(main, pendingIntent, IntentFilter, techListsArray);
						
					}
				} catch (e) {
					//TODO handle the exception
				}
			},
			//获取ic卡数据
			NFCReadUID() {
				var main = plus.android.runtimeMainActivity();
				var _intent = main.getIntent();
				var _action = _intent.getAction();
				console.log("action type:" + _action);

				if (NfcAdapter.ACTION_NDEF_DISCOVERED == _action || NfcAdapter.ACTION_TAG_DISCOVERED == _action ||
					NfcAdapter.ACTION_TECH_DISCOVERED == _action) {
					console.log("选择的调动标签", _intent.getAction())
					var Tag = plus.android.importClass('android.nfc.Tag');
					var bind_codes;
					var tagFromIntent = _intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
					console.log("TAG", tagFromIntent)
					var Ndef = plus.android.importClass("android.nfc.tech.Ndef")
					var ndef = Ndef.get(tagFromIntent)
					
					var NfcA = plus.android.importClass("android.nfc.tech.NfcV")
					console.log("NfcV", NfcA)
					var test_A = NfcA.get(tagFromIntent)
					console.log("get", test_A)
					test_A.close();
					test_A.connect();
					console.log("连接情况", test_A.isConnected())
					var tagUid = tagFromIntent.getId()
					
					// 使用NfcV扇区读取,未完善
					// var blockAddress =127;//块地址
					// var blocknum = 5	
					// var cmd = [];
					// cmd[0] = 0x22;
					// cmd[1] = 0x23;
					// for (var i in tagUid) {
					// 		console.log("传ID:",tagUid[i]);  
					// 		cmd.push(tagUid[i]);
					// }
					// cmd[10] = blockAddress & 0x0ff;
					// cmd[11] = (blocknum - 1) & 0x0ff;
					// console.log('cmd',cmd);
					// var response = test_A.transceive(cmd);
					// console.log("读取数据:",response)
					// var str1 = ""
					// var str2 = ""
					// str1 = this.Bytes2HexString(response);
					// console.log("转化为1",str1)
					// str2 = this.utf8to16(this.hexToString(str1));
					// console.log("转化为2:",str2)
					
					var bind_code = _intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
					// ic卡号 进制转换 
					bind_codes = this.Bytes2HexString(bind_code);
					
					//使用NDEF读取有效记录
					var Parcelable = plus.android.importClass("android.os.Parcelable"); 
					// var rawMsgs = _intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
					var rawMsgs = _intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
					
					if (rawMsgs != null) {
						console.log("读取MSG", rawMsgs) 
						console.log("MSG[0]",rawMsgs[0])
						try{
							var records = rawMsgs[0].getRecords();
							var result = records[0].getPayload();
							console.log("result",result)
							var s = plus.android.newObject("java.lang.String", result);  
							console.log(s); 
							
						}catch(e){
							console.log("错误:",e)
						}
					} else {
						console.log("非NDEF,无法读取MSG")
					}

					this.formData.bind_code = bind_codes
					var tagid = this.reverseTwo(this.bytesToHexString(tagFromIntent.getId()));
					let icId = parseInt(tagid, 16) + '';
					//当ic卡号不到10位的时候 前面自动添加0  补齐10位
					icId = icId.length < 10 ? (Array(10).join(0) + icId).slice(-10) : icId;
					if (icId) {
						this.$emit("changeNfc", {
							tagid: icId,
							action: _action,
							Tag: Tag,
							tagFromIntent: tagFromIntent,
							rawMsgs: s,
							bind_code: bind_code,
							
						})
					} else {
						uni.showToast({
							title: "读取数据失败,请重新读取",
							icon: 'none'
						})
					}
					//关闭遮罩
					this.$refs.popup.close();
				}
			},
			reverseTwo(str) {
				var str1 = "";
				for (var i = 1; i <= str.length; i++) {
					str1 += str[i - 1];
					if (i % 2 == 0) {
						if (i == str.length) {
							break;
						}
						str1 += ":";
					}
				}
				var str2 = "";
				for (var i = str1.split(":").length - 1; i >= 0; i--) {
					str2 += str1.split(":")[i];
				}
				return str2;
			},
			bytesToHexString(inarray) {
				var i, j, x;
				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) {
					x = parseInt(inarray[j]) & 0xff;
					i = (x >> 4) & 0x0f;
					out += hex[i];
					i = x & 0x0f;
					out += hex[i];
				}
				return out;
			},

			//将byte[] 转为Hex,
			Bytes2HexString(arrBytes) {
				var str = '';
				for (var i = 0; i < arrBytes.length; i++) {
					var tmp;
					var num = arrBytes[i];
					if (num < 0) {
						//Java中数值是以补码的形式存在的,应用程序展示的十进制是补码对应真值。补码的存在主要为了简化计算机底层的运算,将减法运算直接当加法来做
						tmp = (255 + num + 1).toString(16);
					} else {
						tmp = num.toString(16);
					}
					if (tmp.length == 1) {
						tmp = '0' + tmp;
					}
					str += tmp;
				}
				return str;
			},
			byteToString(arr) {  
			    if(typeof arr === 'string') {  
			        return arr;  
			    }  
			    var str = '',  
			        _arr = arr;  
			    for(var i = 0; i < _arr.length; i++) {  
			        var one = _arr[i].toString(2),  
			            v = one.match(/^1+?(?=0)/);  
			        if(v && one.length == 8) {  
			            var bytesLength = v[0].length;  
			            var store = _arr[i].toString(2).slice(7 - bytesLength);  
			            for(var st = 1; st < bytesLength; st++) {  
			                store += _arr[st + i].toString(2).slice(2);  
			            }  
			            str += String.fromCharCode(parseInt(store, 2));  
			            i += bytesLength - 1;  
			        } else {  
			            str += String.fromCharCode(_arr[i]);  
			        }  
			    }  
			    return str;  
			},
			hexToString(str){
			  var val="",len = str.length/2;
			  for(var i = 0; i < len; i++){
			    val += String.fromCharCode(parseInt(str.substr(i*2,2),16));
			  }
				console.log(val,'16进制转字符串')
				// this.utf8to16(val);
				return val
			},
			//处理中文乱码问题
			utf8to16(str) {
				var that = this
			  var out, i, len, c;
			  var char2, char3;
			  out = "";
			  len = str.length;
			  i = 0;
			  while(i < len) {
			 	c = str.charCodeAt(i++);
			 	switch(c >> 4){ 
			   		case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
				 		out += str.charAt(i-1);
				 	break;
			   		case 12: case 13:
				 		char2 = str.charCodeAt(i++);
				 		out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
				 	break;
			   		case 14:
				 		char2 = str.charCodeAt(i++);
				 		char3 = str.charCodeAt(i++);
				 		out += String.fromCharCode(((c & 0x0F) << 12) |
						((char2 & 0x3F) << 6) |
						((char3 & 0x3F) << 0));
				 	break;
			  	}
			  }
				console.log(out,'out')
				return out;
				
			},
			
		}
	}
</script>
  •  書き込み操作
write() {
				var main = plus.android.runtimeMainActivity();
				var intent = main.getIntent();
				try {
					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", "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不允许写入");
							uni.showToast({
								title: "tag不允许写入.",
								icon: "none"
							});
						}
						if (ndef.getMaxSize() < size) {
							console.log("文件大小超出容量");
							// waiting.close();
							uni.showToast({
								title: "文件大小超出容量.",
								icon: "none"
							});
							
						}
						// console.log('写入数据:' + JSON.stringify(message) + ' __TYPE__: ' + JSON.stringify(message.__TYPE__));  
						console.log("message:" + message)
						ndef.writeNdefMessage(message);

						console.log("写入数据成功.");
						uni.showToast({
							title: "写入数据成功.",
							icon: "none"
						});
					} else {
						console.log("不支持NdefFormatable写入,该方法使用需要格式化tag并且写入message")
						// var format = NdefFormatable.get(tag);
						// if (format != null) {
						// 	try {
						// 		format.connect();
						// 		format.format(message);
						// 		console.log("格式化tag并且写入message")	
						// 	} catch (e) {
						// 		console.log("格式化tag失败.");
						// 		uni.showToast({
						// 			title: "格式化tag失败.",
						// 			icon: "none"
						// 		});			
						// 	}
						// } else {
						// 	console.log("Tag不支持NDEF");
						// 	uni.showToast({
						// 		title: "Tag不支持NDEF",
						// 		icon: "none"
						// 	});
						// }
					}
				} catch (e) {
					console.log("error=" + e);
					// waiting.close();
					console.log('写入失败');
				}
			},

おすすめ

転載: blog.csdn.net/qq_45020145/article/details/122606026