<template>
|
<view />
|
</template>
|
|
<script>
|
let mainActivity;
|
let receiver;
|
let intentFilter;
|
let isRegistered = false;
|
let lock = false;
|
|
export default {
|
name: "PdaScan",
|
props: {
|
active: { type: Boolean, default: true },
|
eventName: { type: String, default: "scan" },
|
action: { type: String, default: "" },
|
extraKey: { type: String, default: "" },
|
debounceMs: { type: Number, default: 150 },
|
},
|
data() {
|
return {
|
_ensureTimer: null,
|
_ensureTries: 0,
|
};
|
},
|
mounted() {
|
this.ensureStarted();
|
},
|
onHide() {
|
this.stop();
|
},
|
beforeUnmount() {
|
this.stop();
|
},
|
watch: {
|
active(val) {
|
if (val) {
|
this.ensureStarted();
|
} else {
|
this.stop();
|
}
|
},
|
},
|
methods: {
|
ensureStarted() {
|
if (!this.active) return;
|
this._ensureTries = 0;
|
if (this._ensureTimer) {
|
clearInterval(this._ensureTimer);
|
this._ensureTimer = null;
|
}
|
|
const tick = () => {
|
if (!this.active) return;
|
if (isRegistered) return;
|
this.init();
|
this.start();
|
this._ensureTries += 1;
|
if (isRegistered) {
|
if (this._ensureTimer) {
|
clearInterval(this._ensureTimer);
|
this._ensureTimer = null;
|
}
|
} else if (this._ensureTries >= 50) {
|
if (this._ensureTimer) {
|
clearInterval(this._ensureTimer);
|
this._ensureTimer = null;
|
}
|
}
|
};
|
|
tick();
|
if (!isRegistered) {
|
this._ensureTimer = setInterval(tick, 200);
|
}
|
},
|
canUseAndroidBroadcast() {
|
try {
|
if (typeof plus === "undefined") return false;
|
if (!plus.os || plus.os.name !== "Android") return false;
|
if (!plus.android) return false;
|
return true;
|
} catch (e) {
|
return false;
|
}
|
},
|
resolveBroadcastConfig(sys) {
|
try {
|
const brand = String(sys?.brand || "").toUpperCase();
|
const model = String(sys?.model || "").toUpperCase();
|
if (
|
brand.includes("DROI") ||
|
model.includes("MV-IDP5204") ||
|
model.includes("IDP")
|
) {
|
return { action: "com.service.scanner.data", extraKey: "ScanCode" };
|
}
|
} catch (e) {}
|
if (this.action && this.extraKey) {
|
return { action: this.action, extraKey: this.extraKey };
|
}
|
|
return { action: "com.service.scanner.data", extraKey: "ScanCode" };
|
},
|
init() {
|
if (!this.canUseAndroidBroadcast()) return;
|
if (mainActivity && receiver && intentFilter) return;
|
|
let sys = {};
|
try {
|
sys = uni.getSystemInfoSync() || {};
|
} catch (e) {
|
sys = {};
|
}
|
|
const cfg = this.resolveBroadcastConfig(sys);
|
if (!cfg.action || !cfg.extraKey) return;
|
this.initAndroidReceiver(cfg.action, cfg.extraKey);
|
},
|
initAndroidReceiver(action, extraKey) {
|
const _this = this;
|
mainActivity = plus.android.runtimeMainActivity();
|
const IntentFilter = plus.android.importClass(
|
"android.content.IntentFilter"
|
);
|
intentFilter = new IntentFilter();
|
const pickActions = v => {
|
const list = [];
|
if (v) {
|
String(v)
|
.split(/[,\s]+/)
|
.map(s => s.trim())
|
.filter(Boolean)
|
.forEach(a => list.push(a));
|
}
|
[
|
"com.service.scanner.data",
|
"com.scanner.broadcast",
|
"com.android.scanner.broadcast",
|
"com.seuic.scanner.data",
|
"com.android.scanner.receiver",
|
"com.android.scanner.result",
|
"com.rfid.SCAN",
|
"com.honeywell.decode.intent.action",
|
"com.symbol.datawedge.data",
|
"com.symbol.datawedge.api.RESULT_ACTION",
|
"com.datalogic.decodewedge.decode_action",
|
"android.intent.ACTION_DECODE_DATA",
|
"android.intent.action.SCANRESULT",
|
"android.intent.action.DECODE_DATA",
|
"scan.rcv.message",
|
].forEach(a => {
|
if (!list.includes(a)) list.push(a);
|
});
|
return list;
|
};
|
|
const actions = pickActions(action);
|
actions.forEach(a => intentFilter.addAction(a));
|
|
const pickExtraKeys = key => {
|
const list = [];
|
if (key) {
|
String(key)
|
.split(/[,\s]+/)
|
.map(s => s.trim())
|
.filter(Boolean)
|
.forEach(k => list.push(k));
|
}
|
[
|
"ScanCode",
|
"scanCode",
|
"barcode",
|
"barCode",
|
"data",
|
"DATA",
|
"code",
|
"CODE",
|
"result",
|
"RESULT",
|
"scannerdata",
|
"decode_data",
|
"SCAN_RESULT",
|
"data_string",
|
"com.symbol.datawedge.data_string",
|
"com.symbol.datawedge.label_type",
|
].forEach(k => {
|
if (!list.includes(k)) list.push(k);
|
});
|
return list;
|
};
|
|
const extraKeys = pickExtraKeys(extraKey);
|
|
receiver = plus.android.implements(
|
"io.dcloud.feature.internal.reflect.BroadcastReceiver",
|
{
|
onReceive(context, intent) {
|
plus.android.importClass(intent);
|
let code = "";
|
for (let i = 0; i < extraKeys.length; i++) {
|
const k = extraKeys[i];
|
try {
|
const v = intent.getStringExtra(k);
|
if (v) {
|
code = v;
|
break;
|
}
|
} catch (e) {}
|
try {
|
const bytes = intent.getByteArrayExtra(k);
|
if (bytes && bytes.length) {
|
const JString = plus.android.importClass("java.lang.String");
|
code = new JString(bytes);
|
if (code) break;
|
}
|
} catch (e) {}
|
}
|
if (!code) {
|
try {
|
const ds = intent.getDataString();
|
if (ds) code = ds;
|
} catch (e) {}
|
}
|
if (!code) {
|
try {
|
const extras = intent.getExtras();
|
if (extras) {
|
plus.android.importClass(extras);
|
const keySet = extras.keySet();
|
if (keySet) {
|
plus.android.importClass(keySet);
|
const it = keySet.iterator();
|
if (it) {
|
plus.android.importClass(it);
|
while (it.hasNext()) {
|
const k = it.next();
|
const ks = String(k);
|
let v = "";
|
try {
|
v = extras.getString(ks);
|
} catch (e) {}
|
if (!v) {
|
try {
|
const any = extras.get(ks);
|
if (any != null) v = String(any);
|
} catch (e) {}
|
}
|
const text = (v == null ? "" : String(v))
|
.replace(/\n/g, "")
|
.trim();
|
if (
|
text &&
|
text.length >= 3 &&
|
text.length <= 300 &&
|
/[0-9A-Za-z]/.test(text) &&
|
!text.includes("android.") &&
|
!text.includes("com.")
|
) {
|
code = text;
|
break;
|
}
|
if (
|
!code &&
|
text &&
|
text.length >= 3 &&
|
text.length <= 300 &&
|
/[0-9A-Za-z]/.test(text)
|
) {
|
code = text;
|
}
|
}
|
}
|
}
|
}
|
} catch (e) {}
|
}
|
_this.emitCode(code);
|
},
|
}
|
);
|
},
|
start() {
|
if (!this.canUseAndroidBroadcast()) return;
|
if (!mainActivity || !receiver || !intentFilter) return;
|
if (isRegistered) return;
|
try {
|
mainActivity.registerReceiver(receiver, intentFilter);
|
isRegistered = true;
|
} catch (e) {
|
isRegistered = false;
|
}
|
},
|
stop() {
|
if (this._ensureTimer) {
|
clearInterval(this._ensureTimer);
|
this._ensureTimer = null;
|
}
|
if (!this.canUseAndroidBroadcast()) return;
|
if (!mainActivity || !receiver) return;
|
if (!isRegistered) return;
|
try {
|
mainActivity.unregisterReceiver(receiver);
|
} catch (e) {}
|
isRegistered = false;
|
},
|
emitCode(code) {
|
const value = code == null ? "" : String(code);
|
const text = value.replace(/\n/g, "").trim();
|
if (!text) return;
|
|
if (lock) return;
|
lock = true;
|
setTimeout(() => {
|
lock = false;
|
}, this.debounceMs);
|
|
const payload = { code: text };
|
uni.$emit(this.eventName, payload);
|
this.$emit("scan", payload);
|
},
|
},
|
};
|
</script>
|