Files
r-util-js/packages/uni-app/src/nfc/android.js
T

207 lines
5.7 KiB
JavaScript
Raw Normal View History

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();
return await new Promise(async (resolve, reject) => {
await androidNfcUtil.startNfcScan();
androidNfcUtil.addDiscoveredListener((res) => {
androidNfcUtil.stopNfcScan();
resolve(res);
});
});
}
}