export const SCAN_BROADCAST_ACTION = 'android.intent.action.SCANRESULT' export const SCAN_BROADCAST_EXTRA = 'value' export const SCAN_BROADCAST_ACTIONS = Object.freeze([ SCAN_BROADCAST_ACTION, 'com.android.server.scannerservice.broadcast', 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED' ]) const SCAN_BROADCAST_EXTRAS = Object.freeze(['value', 'data', 'barcode', 'SCAN_BARCODE1']) const DUPLICATE_WINDOW_MS = 80 let receiver = null let activity = null let lastScan = { value: '', receivedAt: 0 } export function normalizeScanValue(value) { if (value === null || value === undefined) return '' return String(value).trim() } export function isDuplicateScan(value, receivedAt = Date.now()) { const duplicate = value === lastScan.value && receivedAt - lastScan.receivedAt < DUPLICATE_WINDOW_MS if (!duplicate) lastScan = { value, receivedAt } return duplicate } export function resetScanDeduplication() { lastScan = { value: '', receivedAt: 0 } } export function startScanBroadcast({ onScan, onError } = {}) { if (typeof onScan !== 'function') return () => {} // #ifdef APP-PLUS try { if (receiver) stopScanBroadcast() const registeredActivity = plus.android.runtimeMainActivity() const IntentFilter = plus.android.importClass('android.content.IntentFilter') const filter = new IntentFilter() SCAN_BROADCAST_ACTIONS.forEach((action) => filter.addAction(action)) const registeredReceiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', { onReceive(context, intent) { try { plus.android.importClass(intent) let rawValue = '' for (const extra of SCAN_BROADCAST_EXTRAS) { try { const candidate = intent.getStringExtra(extra) if (candidate !== null && candidate !== undefined && String(candidate).trim()) { rawValue = candidate; break } } catch (_) {} } const value = normalizeScanValue(rawValue) console.info('[Overseas PDA broadcast] received', { action: intent.getAction(), extras: SCAN_BROADCAST_EXTRAS, rawValue, value }) if (!value) { console.warn('[Overseas PDA broadcast] ignored empty value'); return } if (isDuplicateScan(value)) { console.info('[Overseas PDA broadcast] ignored duplicate', { value }); return } onScan(value) } catch (error) { console.error('[Overseas PDA broadcast] receive failed', { message: error.message }) if (typeof onError === 'function') onError(error) } } }) const Build = plus.android.importClass('android.os.Build') const sdkInt = Number(Build.VERSION.SDK_INT) if (Build.VERSION.SDK_INT >= 33) { const Context = plus.android.importClass('android.content.Context') registeredActivity.registerReceiver(registeredReceiver, filter, Context.RECEIVER_EXPORTED) } else { registeredActivity.registerReceiver(registeredReceiver, filter) } activity = registeredActivity receiver = registeredReceiver let packageName = '' try { packageName = String(registeredActivity.getPackageName()) } catch (_) {} console.info('[Overseas PDA broadcast] receiver registered', { actions: SCAN_BROADCAST_ACTIONS, extras: SCAN_BROADCAST_EXTRAS, packageName, sdkInt, exported: sdkInt >= 33 }) return () => stopRegisteredBroadcast(registeredActivity, registeredReceiver) } catch (error) { console.error('[Overseas PDA broadcast] registration failed', { actions: SCAN_BROADCAST_ACTIONS, extras: SCAN_BROADCAST_EXTRAS, message: error?.message || String(error) }) receiver = null activity = null if (typeof onError === 'function') onError(error) } // #endif return stopScanBroadcast } function stopRegisteredBroadcast(registeredActivity, registeredReceiver) { // #ifdef APP-PLUS if (registeredActivity && registeredReceiver) { try { registeredActivity.unregisterReceiver(registeredReceiver) } catch (_) {} } // #endif if (activity !== registeredActivity || receiver !== registeredReceiver) return receiver = null activity = null resetScanDeduplication() } export function stopScanBroadcast() { stopRegisteredBroadcast(activity, receiver) }