优化
This commit is contained in:
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
"name" : "柏悦物流 PDA 海外版",
|
"name" : "柏悦物流 PDA 海外版",
|
||||||
"appid" : "__UNI__936D079",
|
"appid" : "__UNI__936D079",
|
||||||
"description" : "柏悦物流海外仓 PDA 作业端",
|
"description" : "柏悦物流海外仓 PDA 作业端",
|
||||||
"versionName" : "0.0.3",
|
"versionName" : "0.0.4",
|
||||||
"versionCode" : 3,
|
"versionCode" : 4,
|
||||||
"transformPx" : false,
|
"transformPx" : false,
|
||||||
"app-plus" : {
|
"app-plus" : {
|
||||||
"usingComponents" : true,
|
"usingComponents" : true,
|
||||||
|
|||||||
+36
-16
@@ -1,5 +1,11 @@
|
|||||||
export const SCAN_BROADCAST_ACTION = 'android.intent.action.SCANRESULT'
|
export const SCAN_BROADCAST_ACTION = 'android.intent.action.SCANRESULT'
|
||||||
export const SCAN_BROADCAST_EXTRA = 'value'
|
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
|
const DUPLICATE_WINDOW_MS = 80
|
||||||
|
|
||||||
@@ -29,17 +35,23 @@ export function startScanBroadcast({ onScan, onError } = {}) {
|
|||||||
try {
|
try {
|
||||||
if (receiver) stopScanBroadcast()
|
if (receiver) stopScanBroadcast()
|
||||||
|
|
||||||
activity = plus.android.runtimeMainActivity()
|
const registeredActivity = plus.android.runtimeMainActivity()
|
||||||
const IntentFilter = plus.android.importClass('android.content.IntentFilter')
|
const IntentFilter = plus.android.importClass('android.content.IntentFilter')
|
||||||
const filter = new IntentFilter()
|
const filter = new IntentFilter()
|
||||||
filter.addAction(SCAN_BROADCAST_ACTION)
|
SCAN_BROADCAST_ACTIONS.forEach((action) => filter.addAction(action))
|
||||||
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
|
const registeredReceiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
|
||||||
onReceive(context, intent) {
|
onReceive(context, intent) {
|
||||||
try {
|
try {
|
||||||
plus.android.importClass(intent)
|
plus.android.importClass(intent)
|
||||||
const rawValue = intent.getStringExtra(SCAN_BROADCAST_EXTRA)
|
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)
|
const value = normalizeScanValue(rawValue)
|
||||||
console.info('[Overseas PDA broadcast] received', { action: intent.getAction(), extra: SCAN_BROADCAST_EXTRA, rawValue, value })
|
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 (!value) { console.warn('[Overseas PDA broadcast] ignored empty value'); return }
|
||||||
if (isDuplicateScan(value)) { console.info('[Overseas PDA broadcast] ignored duplicate', { value }); return }
|
if (isDuplicateScan(value)) { console.info('[Overseas PDA broadcast] ignored duplicate', { value }); return }
|
||||||
onScan(value)
|
onScan(value)
|
||||||
@@ -53,23 +65,26 @@ export function startScanBroadcast({ onScan, onError } = {}) {
|
|||||||
const sdkInt = Number(Build.VERSION.SDK_INT)
|
const sdkInt = Number(Build.VERSION.SDK_INT)
|
||||||
if (Build.VERSION.SDK_INT >= 33) {
|
if (Build.VERSION.SDK_INT >= 33) {
|
||||||
const Context = plus.android.importClass('android.content.Context')
|
const Context = plus.android.importClass('android.content.Context')
|
||||||
activity.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED)
|
registeredActivity.registerReceiver(registeredReceiver, filter, Context.RECEIVER_EXPORTED)
|
||||||
} else {
|
} else {
|
||||||
activity.registerReceiver(receiver, filter)
|
registeredActivity.registerReceiver(registeredReceiver, filter)
|
||||||
}
|
}
|
||||||
|
activity = registeredActivity
|
||||||
|
receiver = registeredReceiver
|
||||||
let packageName = ''
|
let packageName = ''
|
||||||
try { packageName = String(activity.getPackageName()) } catch (_) {}
|
try { packageName = String(registeredActivity.getPackageName()) } catch (_) {}
|
||||||
console.info('[Overseas PDA broadcast] receiver registered', {
|
console.info('[Overseas PDA broadcast] receiver registered', {
|
||||||
action: SCAN_BROADCAST_ACTION,
|
actions: SCAN_BROADCAST_ACTIONS,
|
||||||
extra: SCAN_BROADCAST_EXTRA,
|
extras: SCAN_BROADCAST_EXTRAS,
|
||||||
packageName,
|
packageName,
|
||||||
sdkInt,
|
sdkInt,
|
||||||
exported: sdkInt >= 33
|
exported: sdkInt >= 33
|
||||||
})
|
})
|
||||||
|
return () => stopRegisteredBroadcast(registeredActivity, registeredReceiver)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[Overseas PDA broadcast] registration failed', {
|
console.error('[Overseas PDA broadcast] registration failed', {
|
||||||
action: SCAN_BROADCAST_ACTION,
|
actions: SCAN_BROADCAST_ACTIONS,
|
||||||
extra: SCAN_BROADCAST_EXTRA,
|
extras: SCAN_BROADCAST_EXTRAS,
|
||||||
message: error?.message || String(error)
|
message: error?.message || String(error)
|
||||||
})
|
})
|
||||||
receiver = null
|
receiver = null
|
||||||
@@ -81,15 +96,20 @@ export function startScanBroadcast({ onScan, onError } = {}) {
|
|||||||
return stopScanBroadcast
|
return stopScanBroadcast
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopScanBroadcast() {
|
function stopRegisteredBroadcast(registeredActivity, registeredReceiver) {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
if (activity && receiver) {
|
if (registeredActivity && registeredReceiver) {
|
||||||
try {
|
try {
|
||||||
activity.unregisterReceiver(receiver)
|
registeredActivity.unregisterReceiver(registeredReceiver)
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
|
if (activity !== registeredActivity || receiver !== registeredReceiver) return
|
||||||
receiver = null
|
receiver = null
|
||||||
activity = null
|
activity = null
|
||||||
resetScanDeduplication()
|
resetScanDeduplication()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stopScanBroadcast() {
|
||||||
|
stopRegisteredBroadcast(activity, receiver)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,15 +4,23 @@ import { readFile } from 'node:fs/promises'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
SCAN_BROADCAST_ACTION,
|
SCAN_BROADCAST_ACTION,
|
||||||
|
SCAN_BROADCAST_ACTIONS,
|
||||||
SCAN_BROADCAST_EXTRA,
|
SCAN_BROADCAST_EXTRA,
|
||||||
isDuplicateScan,
|
isDuplicateScan,
|
||||||
normalizeScanValue,
|
normalizeScanValue,
|
||||||
resetScanDeduplication
|
resetScanDeduplication,
|
||||||
|
startScanBroadcast,
|
||||||
|
stopScanBroadcast
|
||||||
} from '../src/utils/scan-broadcast.js'
|
} from '../src/utils/scan-broadcast.js'
|
||||||
|
|
||||||
test('scanner uses the confirmed PDA broadcast contract', () => {
|
test('scanner uses the confirmed PDA broadcast contract', () => {
|
||||||
assert.equal(SCAN_BROADCAST_ACTION, 'android.intent.action.SCANRESULT')
|
assert.equal(SCAN_BROADCAST_ACTION, 'android.intent.action.SCANRESULT')
|
||||||
assert.equal(SCAN_BROADCAST_EXTRA, 'value')
|
assert.equal(SCAN_BROADCAST_EXTRA, 'value')
|
||||||
|
assert.deepEqual(SCAN_BROADCAST_ACTIONS, [
|
||||||
|
'android.intent.action.SCANRESULT',
|
||||||
|
'com.android.server.scannerservice.broadcast',
|
||||||
|
'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED'
|
||||||
|
])
|
||||||
assert.equal(normalizeScanValue(' EL-38201\r\n'), 'EL-38201')
|
assert.equal(normalizeScanValue(' EL-38201\r\n'), 'EL-38201')
|
||||||
assert.equal(normalizeScanValue(null), '')
|
assert.equal(normalizeScanValue(null), '')
|
||||||
})
|
})
|
||||||
@@ -25,7 +33,7 @@ test('scanner source keeps receiver diagnostics before page routing', async () =
|
|||||||
assert.match(source, /receive failed/)
|
assert.match(source, /receive failed/)
|
||||||
assert.match(source, /receiver registered/)
|
assert.match(source, /receiver registered/)
|
||||||
assert.match(source, /registration failed/)
|
assert.match(source, /registration failed/)
|
||||||
assert.match(source, /activity\.getPackageName\(\)/)
|
assert.match(source, /registeredActivity\.getPackageName\(\)/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('scanner drops only immediate duplicate broadcasts', () => {
|
test('scanner drops only immediate duplicate broadcasts', () => {
|
||||||
@@ -35,3 +43,40 @@ test('scanner drops only immediate duplicate broadcasts', () => {
|
|||||||
assert.equal(isDuplicateScan('EL-38201', 1100), false)
|
assert.equal(isDuplicateScan('EL-38201', 1100), false)
|
||||||
assert.equal(isDuplicateScan('EL-38202', 1110), false)
|
assert.equal(isDuplicateScan('EL-38202', 1110), false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('an old page disposer cannot unregister the receiver owned by the newly shown page', () => {
|
||||||
|
const registered = []
|
||||||
|
const unregistered = []
|
||||||
|
class IntentFilter { addAction(action) { this.action = action } }
|
||||||
|
const activity = {
|
||||||
|
registerReceiver(value) { registered.push(value) },
|
||||||
|
unregisterReceiver(value) { unregistered.push(value) },
|
||||||
|
getPackageName() { return 'com.baiyuelogistics.pda.overseas' }
|
||||||
|
}
|
||||||
|
globalThis.plus = { android: {
|
||||||
|
runtimeMainActivity: () => activity,
|
||||||
|
importClass(name) {
|
||||||
|
if (name === 'android.content.IntentFilter') return IntentFilter
|
||||||
|
if (name === 'android.os.Build') return { VERSION: { SDK_INT: 32 } }
|
||||||
|
return name
|
||||||
|
},
|
||||||
|
implements: (_name, implementation) => implementation
|
||||||
|
} }
|
||||||
|
try {
|
||||||
|
const stopFirst = startScanBroadcast({ onScan() {} })
|
||||||
|
const first = registered[0]
|
||||||
|
const stopSecond = startScanBroadcast({ onScan() {} })
|
||||||
|
const second = registered[1]
|
||||||
|
assert.deepEqual(unregistered, [first])
|
||||||
|
|
||||||
|
stopFirst()
|
||||||
|
assert.deepEqual(unregistered, [first, first])
|
||||||
|
assert.ok(!unregistered.includes(second))
|
||||||
|
|
||||||
|
stopSecond()
|
||||||
|
assert.equal(unregistered.at(-1), second)
|
||||||
|
} finally {
|
||||||
|
stopScanBroadcast()
|
||||||
|
delete globalThis.plus
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user