2026-05-28 11:30:35 +08:00
|
|
|
/* eslint-disable no-useless-assignment, @typescript-eslint/no-unused-vars */
|
2026-03-16 17:58:57 +08:00
|
|
|
const systemInfo = uni.getSystemInfoSync();
|
|
|
|
|
const isAndroid =
|
|
|
|
|
systemInfo.uniPlatform === "app" && systemInfo.osName === "android";
|
|
|
|
|
|
|
|
|
|
let runtimeMainActivity = null;
|
|
|
|
|
let newObject = null;
|
|
|
|
|
let getAttribute = null;
|
|
|
|
|
let setAttribute = null;
|
|
|
|
|
let importClass = null;
|
|
|
|
|
let invoke = null;
|
|
|
|
|
let Intent = null;
|
|
|
|
|
let Activity = null;
|
|
|
|
|
let PendingIntent = null;
|
|
|
|
|
let IntentFilter = null;
|
|
|
|
|
let NfcAdapter = null;
|
|
|
|
|
let NdefRecord = null;
|
|
|
|
|
let NdefMessage = null;
|
|
|
|
|
let MifareClassic = null;
|
|
|
|
|
let Ndef = null;
|
|
|
|
|
let Tag = null;
|
|
|
|
|
let Parcelable = null;
|
|
|
|
|
let NfcV = null;
|
|
|
|
|
|
|
|
|
|
if (isAndroid) {
|
|
|
|
|
runtimeMainActivity = plus.android.runtimeMainActivity;
|
|
|
|
|
newObject = plus.android.newObject;
|
|
|
|
|
getAttribute = plus.android.getAttribute;
|
|
|
|
|
setAttribute = plus.android.setAttribute;
|
|
|
|
|
importClass = plus.android.importClass;
|
|
|
|
|
invoke = plus.android.invoke;
|
|
|
|
|
|
|
|
|
|
Intent = importClass("android.content.Intent");
|
|
|
|
|
Activity = importClass("android.app.Activity");
|
|
|
|
|
PendingIntent = importClass("android.app.PendingIntent");
|
|
|
|
|
IntentFilter = importClass("android.content.IntentFilter");
|
|
|
|
|
NfcAdapter = importClass("android.nfc.NfcAdapter");
|
|
|
|
|
NdefRecord = importClass("android.nfc.NdefRecord");
|
|
|
|
|
NdefMessage = importClass("android.nfc.NdefMessage");
|
|
|
|
|
MifareClassic = importClass("android.nfc.tech.MifareClassic");
|
|
|
|
|
Ndef = importClass("android.nfc.tech.Ndef");
|
|
|
|
|
Tag = importClass("android.nfc.Tag");
|
|
|
|
|
Parcelable = importClass("android.os.Parcelable");
|
|
|
|
|
NfcV = importClass("android.nfc.tech.NfcV");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class AndroidNfcUtil {
|
|
|
|
|
main = null;
|
|
|
|
|
nfcAdapter = null;
|
|
|
|
|
pendingIntent = null;
|
|
|
|
|
intentFiltersArray = null;
|
|
|
|
|
techListsArray = null;
|
|
|
|
|
discoveredListenerList = [];
|
|
|
|
|
/**
|
|
|
|
|
* @type {Function}
|
|
|
|
|
*/
|
|
|
|
|
_discoveredHandler = null;
|
|
|
|
|
/**
|
|
|
|
|
* @type {Function}
|
|
|
|
|
*/
|
|
|
|
|
_resumeHandler = null;
|
|
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
|
this.main = runtimeMainActivity();
|
|
|
|
|
this.nfcAdapter = NfcAdapter.getDefaultAdapter(this.main);
|
|
|
|
|
this._discoveredHandler = this.discoveredHandler.bind(this);
|
|
|
|
|
this._resumeHandler = this.resumeHandler.bind(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {Function} cb
|
|
|
|
|
*/
|
|
|
|
|
addDiscoveredListener(cb) {
|
|
|
|
|
this.discoveredListenerList.push(cb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 是否支持NFC
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
static isNfcSupported() {
|
|
|
|
|
const main = runtimeMainActivity();
|
|
|
|
|
const nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
|
|
|
|
return nfcAdapter != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 是否开启NFC
|
|
|
|
|
* @returns {boolean} true 已开启
|
|
|
|
|
*/
|
|
|
|
|
static async isNfcEnabled() {
|
|
|
|
|
const main = runtimeMainActivity();
|
|
|
|
|
const nfcAdapter = NfcAdapter.getDefaultAdapter(main);
|
|
|
|
|
return nfcAdapter && nfcAdapter.isEnabled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @returns {Promise<number[]>}
|
|
|
|
|
*/
|
|
|
|
|
async startNfcScan() {
|
|
|
|
|
console.log("startNfcScan", this.nfcAdapter);
|
|
|
|
|
|
|
|
|
|
if (this.nfcAdapter == null) {
|
|
|
|
|
throw new Error("该设备不支持NFC");
|
|
|
|
|
} else if (!this.nfcAdapter.isEnabled()) {
|
|
|
|
|
throw new Error("未开启NFC");
|
|
|
|
|
} else {
|
|
|
|
|
return await this.init();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async stopNfcScan() {
|
|
|
|
|
console.log("stopNfcScan");
|
|
|
|
|
plus.globalEvent.removeEventListener("newintent", this._discoveredHandler);
|
|
|
|
|
plus.globalEvent.removeEventListener("resume", this._discoveredHandler);
|
|
|
|
|
this.nfcAdapter.disableForegroundDispatch(this.main);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化ncf 并开启监听
|
|
|
|
|
*/
|
|
|
|
|
async init() {
|
|
|
|
|
console.log("init");
|
|
|
|
|
const ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
|
|
|
|
const tag = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
|
|
|
|
|
const tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
|
|
|
|
|
this.intentFiltersArray = [ndef, tag, tech];
|
|
|
|
|
|
|
|
|
|
this.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"],
|
|
|
|
|
];
|
|
|
|
|
const intent = new Intent(this.main, this.main.getClass());
|
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
|
|
|
|
|
|
|
|
this.pendingIntent = PendingIntent.getActivity(this.main, 0, intent, 0);
|
|
|
|
|
|
|
|
|
|
this.nfcAdapter.enableForegroundDispatch(
|
|
|
|
|
this.main,
|
|
|
|
|
this.pendingIntent,
|
|
|
|
|
this.intentFiltersArray,
|
|
|
|
|
this.techListsArray,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
plus.globalEvent.addEventListener("newintent", this._discoveredHandler);
|
|
|
|
|
plus.globalEvent.addEventListener("resume", this._resumeHandler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resumeHandler() {
|
|
|
|
|
console.log("resumeHandler");
|
|
|
|
|
this.nfcAdapter.enableForegroundDispatch(
|
|
|
|
|
this.main,
|
|
|
|
|
this.pendingIntent,
|
|
|
|
|
this.intentFiltersArray,
|
|
|
|
|
this.techListsArray,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
discoveredHandler() {
|
|
|
|
|
console.log("discoveredHandler");
|
|
|
|
|
this.discoveredListenerList.forEach((cb) => {
|
|
|
|
|
cb(this.readId());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
readId() {
|
|
|
|
|
console.log("readId");
|
|
|
|
|
|
|
|
|
|
const intent = this.main.getIntent();
|
|
|
|
|
const action = intent.getAction();
|
|
|
|
|
console.log("action: " + action);
|
|
|
|
|
|
|
|
|
|
// if (
|
|
|
|
|
// NfcAdapter.ACTION_NDEF_DISCOVERED == action ||
|
|
|
|
|
// NfcAdapter.ACTION_TAG_DISCOVERED == action ||
|
|
|
|
|
// NfcAdapter.ACTION_TECH_DISCOVERED == action
|
|
|
|
|
// ) {
|
|
|
|
|
console.log("intent.getAction()", intent.getAction());
|
|
|
|
|
const tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
|
|
|
|
console.log("tagFromIntent.getId", tagFromIntent.getId());
|
|
|
|
|
return tagFromIntent.getId();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static async scan() {
|
|
|
|
|
const androidNfcUtil = new AndroidNfcUtil();
|
2026-05-28 11:30:35 +08:00
|
|
|
return await new Promise((resolve, reject) => {
|
|
|
|
|
androidNfcUtil
|
|
|
|
|
.startNfcScan()
|
|
|
|
|
.then(() => {
|
|
|
|
|
androidNfcUtil.addDiscoveredListener((res) => {
|
|
|
|
|
androidNfcUtil.stopNfcScan();
|
|
|
|
|
resolve(res);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch(reject);
|
2026-03-16 17:58:57 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|