let NfcAdapter; let nfc; let nfcCallback; let NdefRecord; let NdefMessage; let nfcType = 'cardNo' let nfcwriteText = '' export function initNFC(callback) { if (uni.getSystemInfoSync().platform == 'android') { nfcCallback = callback; init(); } } export function closeNFC() { nfcCallback = null; if (uni.getSystemInfoSync().platform == 'android') { close(); } } export function setNfcType(e) { if (!['cardNo', 'write', 'read'].includes(e)) { showToast('类型不正确') return } nfcType = e } export function setNfcText(e) { nfcwriteText = e } function showToast(msg) { uni.showToast({ title: msg, icon: 'none' }) } function init() { 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'); nfc = NfcAdapter.getDefaultAdapter(main); if (nfc == null) { uni.showToast({ title: '设备不支持NFC!', icon: 'none' }) return; } if (!nfc.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"); let tag = new IntentFilter('android.nfc.action.TAG_DISCOVERED'); ndef.addDataType("*/*"); let intentFiltersArray = [ndef, tag]; let techListsArray = [ ["android.nfc.tech.MifareClassic"], ["android.nfc.tech.MifareUltralight"] ]; plus.globalEvent.addEventListener("newintent", function() { readCardNo(); }, false); plus.globalEvent.addEventListener("pause", function(e) { if (nfc) { nfc.disableForegroundDispatch(main); } }, false); plus.globalEvent.addEventListener("resume", function(e) { if (nfc) { nfc.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray); } }, false); nfc.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray); } catch (e) { console.error(e); } } /** * 监听 */ function readCardNo() { NdefRecord = plus.android.importClass("android.nfc.NdefRecord"); NdefMessage = plus.android.importClass("android.nfc.NdefMessage"); var main = plus.android.runtimeMainActivity(); var intent = main.getIntent(); if ("android.nfc.action.TECH_DISCOVERED" == intent.getAction()) { if (nfcType === 'cardNo') { __read_no(intent) } else if (nfcType === 'write') { __write(intent); } else { __read(intent); } } } /** * 写入内容 */ function __write(intent) { if (!nfcwriteText) { showToast('写入内容不能为空') return } var text = nfcwriteText var textBytes = plus.android.invoke(text, "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()) { nfcCallback({ code: 500, data: { type: nfcType, text: text, }, message: 'tag不允许写入' }) return; } if (ndef.getMaxSize() < size) { nfcCallback({ code: 500, data: { type: nfcType, text: text, }, message: '文件大小超出容量' }) return; } ndef.writeNdefMessage(message); nfcCallback({ code: 200, data: { type: nfcType, text: text, }, message: '写入成功' }) return; } else { var format = NdefFormatable.get(tag); if (format != null) { try { format.connect(); format.format(message); nfcCallback({ code: 500, data: { type: nfcType, text: text, }, message: '格式化tag并且写入message' }) return; } catch (e) { nfcCallback({ code: 500, data: { type: nfcType, text: text, }, message: '格式化tag失败' }) return; } } else { nfcCallback({ code: 500, data: { type: nfcType, text: text, }, message: 'Tag不支持NDEF' }) return; } } } /** * 读取内容 */ function __read(intent) { var Parcelable = plus.android.importClass("android.os.Parcelable"); var rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES"); if (rawmsgs) { const records = rawmsgs[0].getRecords(); var result = records[0].getPayload(); var s = plus.android.newObject("java.lang.String", result); if (typeof s === 'string') { nfcCallback({ code: 200, data: { type: nfcType, text: s, }, message: '读取成功' }) } else { nfcCallback({ code: 500, data: { type: nfcType, text: s, }, message: '数据为空' }) } } else { nfcCallback({ code: 500, data: { type: nfcType, text: '', }, message: '数据为空' }) } } /** * 读取卡号 */ function __read_no(intent) { var content = ""; var tag = plus.android.importClass("android.nfc.Tag"); tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); var bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID); content += "卡片字节数组ID:" + tag.getId() + "
"; content += "卡片16进制ID:" + ab2hex(tag.getId()) + "
"; var tagid = ab2hex(tag.getId()); content += "卡片16进制翻转ID:" + tagid + "
"; content += "卡片10进制卡号:" + parseInt(tagid, 16) + "
"; nfcCallback({ code: 200, data: { type: nfcType, id: tagid, reverseTagId16: tagid, tagId16: ab2hex(tag.getId()), bytesIds: tag.getId() }, message: '读取成功' }) console.log(content) } function ab2hex(buffer) { const hexArr = Array.prototype.map.call( new Uint8Array(buffer), function(bit) { return ('00' + bit.toString(16)).slice(-2).toUpperCase(); } ) return hexArr.join('') } function close() { if (nfc) { let main = plus.android.runtimeMainActivity(); nfc.disableForegroundDispatch(main); } }