/** * 初始化参数 */ //#ifdef APP-PLUS let UsbManager = plus.android.importClass("android.hardware.usb.UsbManager"); let IntentFilter = plus.android.importClass("android.content.IntentFilter"); let PendingIntent = plus.android.importClass("android.app.PendingIntent"); let UsbConstants = plus.android.importClass( "android.hardware.usb.UsbConstants" ); let UsbInterface = plus.android.importClass( "android.hardware.usb.UsbInterface" ); let Intent = plus.android.importClass("android.content.Intent"); let Context = plus.android.importClass("android.content.Context"); let HashMap = plus.android.importClass("java.util.HashMap"); let Toast = plus.android.importClass("android.widget.Toast"); let invoke = plus.android.invoke; let activity = plus.android.runtimeMainActivity(); const VIDQR = 0x09c5; const VIDMY = 0x09c6; const VIDIP = 0x353d; const deviceList = []; let mPermissionIntent = null; let mUsbManager = null; let currentDevice = null; let mUsbDeviceConnection = null; let mUsbInterface = null; let mUsbEndpointIn = null; let mUsbEndpointOut = null; let usbStatusReceiver = null; //usb状态监听广播 let isOpen = false; //#endif /** * 构造对象 */ var usbTool = { state: { USBState: "", readThreadState: false, //数据读取线程状态 }, options: { /** * 监听USB状态回调 * @param {String} state */ listenUSBStatusCallback: function (state) {}, /** * 接收到数据回调 * @param {Array} dataByteArr */ readDataCallback: function (dataByteArr) {}, }, init(setOptions) { Object.assign(this.options, setOptions); this.listenUsbStatus(); mUsbManager = activity.getSystemService(Context.USB_SERVICE); mPermissionIntent = PendingIntent.getBroadcast( activity, 0, new Intent("com.application.usbhost.USB_PERMISSION"), PendingIntent.FLAG_IMMUTABLE ); }, shortToast(msg) { Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); }, // 打开设备 async openUsb() { let mDevices = new HashMap(); mDevices = mUsbManager.getDeviceList(); if (mDevices === null) return false; const devicesSize = invoke(mDevices, "size"); //获取几个长度 if (devicesSize === 0) return false; const values = invoke(mDevices, "values"); const iterator = invoke(values, "iterator"); while (invoke(iterator, "hasNext")) { const device = invoke(iterator, "next"); const vendorId = invoke(device, "getVendorId"); // 获取vendorId if (vendorId == VIDQR || vendorId == VIDMY || vendorId == VIDIP) { currentDevice = device; if (!mUsbManager.hasPermission(currentDevice)) { // 获取权限弹框 mUsbManager.requestPermission(currentDevice, mPermissionIntent); for (let i = 10; i > 0; i--) { await this.delay(1000); if (i == 1 && !mUsbManager.hasPermission(currentDevice)) { return false; } if (mUsbManager.hasPermission(currentDevice)) { break; } } } if ( this.initCommunication(currentDevice, UsbConstants.USB_CLASS_PRINTER) ) { return true; } } } return false; }, delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }, initCommunication(device, type) { const interfaceCount = invoke(device, "getInterfaceCount"); //获取接口数量 for ( let interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++ ) { const usbInterface = invoke(device, "getInterface", interfaceIndex); // 遍历获取接口 const interfaceClass = invoke(usbInterface, "getInterfaceClass"); if (type != interfaceClass) { continue; } mUsbInterface = usbInterface; for (let i = 0; i < invoke(usbInterface, "getEndpointCount"); i++) { const ep = invoke(usbInterface, "getEndpoint", i); if (invoke(ep, "getType") == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (invoke(ep, "getDirection") == UsbConstants.USB_DIR_OUT) { mUsbEndpointOut = ep; } else if (invoke(ep, "getDirection") == UsbConstants.USB_DIR_IN) { mUsbEndpointIn = ep; } } } if (null == mUsbEndpointIn || null == mUsbEndpointOut) { mUsbEndpointIn = null; mUsbEndpointOut = null; isOpen = false; return false; } else { if (!mUsbManager.hasPermission(currentDevice)) { isOpen = false; return false; } else { isOpen = true; return true; } } } return false; }, /** * usb状态监听 * @param {Activity} activity */ listenUsbStatus() { if (usbStatusReceiver != null) { try { activity.unregisterReceiver(usbStatusReceiver); } catch (e) { console.error(e); } usbStatusReceiver = null; } usbStatusReceiver = plus.android.implements( "io.dcloud.android.content.BroadcastReceiver", { onReceive: (context, intent) => { plus.android.importClass(context); plus.android.importClass(intent); let action = intent.getAction(); switch (action) { case UsbManager.ACTION_USB_DEVICE_ATTACHED: this.options.listenUSBStatusCallback && this.options.listenUSBStatusCallback( "ACTION_USB_DEVICE_ATTACHED" ); break; case UsbManager.ACTION_USB_DEVICE_DETACHED: isOpen = false; this.options.listenUSBStatusCallback && this.options.listenUSBStatusCallback( "ACTION_USB_DEVICE_DETACHED" ); break; } }, } ); let filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); activity.registerReceiver(usbStatusReceiver, filter); }, /** * 关闭usb */ closeUsb() { mUsbEndpointIn = null; mUsbEndpointOut = null; if (mUsbDeviceConnection != null) { mUsbDeviceConnection.releaseInterface(mUsbInterface); mUsbDeviceConnection.close(); mUsbDeviceConnection = null; isOpen = false; } }, /** * 获得usb打开状态 * * @return true:USB打开 false:USB关闭 */ isOpened() { return isOpen; }, sendByteData(byteData) { if (currentDevice == null) { console.log("未检测到打印机设备"); return false; } if (mUsbDeviceConnection == null) { mUsbManager.requestPermission(currentDevice, mPermissionIntent); mUsbDeviceConnection = mUsbManager.openDevice(currentDevice); const ret = invoke( mUsbDeviceConnection, "claimInterface", mUsbInterface, true ); } if (mUsbEndpointOut == null) { return false; } const result = invoke( mUsbDeviceConnection, "bulkTransfer", mUsbEndpointOut, byteData, byteData.length, 1500 ); if (result == -1) { return false; } else { return true; } }, }; module.exports = usbTool;