const package_NfcAdapter = 'android.nfc.NfcAdapter';
import { useBluetoothStore } from '@/store/bluetooth'
let NfcAdapter;
let NdefRecord;
let NdefMessage;
let readyWriteData = false;
let readyRead = false;
let noNFC = false;
let techListsArray = [
['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']
];
let text = '{id:123,name:nfc,site:cssmini.com}';
let readResult = '';
export default {
listenNFCStatus() {
try {
let main = plus.android.runtimeMainActivity();
let Intent = plus.android.importClass('android.content.Intent');
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) {
toast('Device does not support NFC');
noNFC = true;
return;
}
if (!nfcAdapter.isEnabled()) {
toast('Please enable NFC in system settings');
noNFC = true;
return;
} else {
noNFC = false;
}
let intent = new Intent(main, main.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
let pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_MUTABLE);
let techFilter = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
let ndefFilter = new IntentFilter("android.nfc.action.NDEF_DISCOVERED");
techFilter.addDataType("*/*");
ndefFilter.addDataType("*/*");
let intentFiltersArray = [techFilter, ndefFilter];
plus.globalEvent.addEventListener('newintent', () => {
console.log('[NFC] newintent received');
setTimeout(() => {
this.nfcRuning();
}, 1000);
});
plus.globalEvent.addEventListener('pause', () => {
console.log('[NFC] app paused, disable foreground dispatch');
if (nfcAdapter) nfcAdapter.disableForegroundDispatch(main);
});
plus.globalEvent.addEventListener('resume', () => {
console.log('[NFC] app resumed, enable foreground dispatch');
if (nfcAdapter) {
nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
}
});
nfcAdapter.enableForegroundDispatch(main, pendingIntent, intentFiltersArray, techListsArray);
} catch (e) {
console.error('[NFC] 初始化异常:', e);
}
},
nfcRuning() {
try {
NdefRecord = plus.android.importClass("android.nfc.NdefRecord");
NdefMessage = plus.android.importClass("android.nfc.NdefMessage");
const main = plus.android.runtimeMainActivity();
const intent = main.getIntent();
const action = intent.getAction();
console.log('[NFC] Action:', action);
if (
action === "android.nfc.action.TECH_DISCOVERED" ||
action === "android.nfc.action.NDEF_DISCOVERED"
) {
if (readyWriteData) {
this.write(intent);
readyWriteData = false;
} else if (readyRead) {
this.read(intent);
readyRead = false;
}
}
} catch (e) {
console.error('[NFC] nfcRuning异常:', e);
}
},
write(intent) {
try {
toast('请勿移开标签,正在写入...');
console.log('[NFC] 准备写入:', text);
const textBytes = plus.android.invoke(text, "getBytes");
const textRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA,
plus.android.invoke("text/plain", "getBytes"),
plus.android.invoke("", "getBytes"),
textBytes
);
const message = new NdefMessage([textRecord]);
const Ndef = plus.android.importClass('android.nfc.tech.Ndef');
const NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');
const tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
const ndef = Ndef.get(tag);
if (ndef) {
const size = message.toByteArray().length;
ndef.connect();
if (!ndef.isWritable()) {
toast('标签不可写');
return;
}
if (ndef.getMaxSize() < size) {
toast('数据超过容量');
return;
}
ndef.writeNdefMessage(message);
toast('写入成功');
} else {
const format = NdefFormatable.get(tag);
if (format) {
format.connect();
format.format(message);
toast('格式化并写入成功');
} else {
toast('不支持NDEF格式');
}
}
} catch (e) {
console.error('[NFC] 写入失败:', e);
toast('写入失败');
}
},
read(intent) {
const bluetoothStore = useBluetoothStore()
try {
const NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
const Parcelable = plus.android.importClass("android.os.Parcelable");
const bytesId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
const nfc_id = this.byteArrayToHexString(bytesId);
console.log('[NFC] 标签ID:', typeof (nfc_id), nfc_id);
bluetoothStore.NfcId = nfc_id;
console.log('[NFC] Pinia标签ID:', bluetoothStore.NfcId);
const rawmsgs = intent.getParcelableArrayExtra("android.nfc.extra.NDEF_MESSAGES");
if (rawmsgs && rawmsgs.length > 0) {
const records = rawmsgs[0].getRecords();
const result = records[0].getPayload();
const data = plus.android.newObject("java.lang.String", result);
const jsData = data + "";
console.log('[NFC] 标签数据:', jsData);
const match = jsData.match(/[?&]chk=([^&]+)/);
const chk = match ? match[1] : null;
console.log('[NFC] 提取到 chk:', chk);
} else {
console.warn('[NFC] 标签没有 NDEF 数据');
}
} catch (e) {
console.error('[NFC] 读取失败:', e);
toast('Reading failed');
}
},
byteArrayToHexString(inarray) {
let out = "";
for (let j = 0; j < inarray.length; ++j) {
const v = inarray[j] & 0xff;
out += (v < 16 ? "0" : "") + v.toString(16).toUpperCase();
}
return out;
},
writeData() {
if (noNFC) {
return;
}
readyWriteData = true;
toast('Please bring the NFC tag close');
},
readData() {
if (noNFC) {
return;
}
readyRead = true;
toast('Please bring the NFC tag close');
}
};
function toast(content) {
uni.showToast({
title: content,
icon: 'none',
duration: 2000
});
}