usbTool.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * 初始化参数
  3. */
  4. //#ifdef APP-PLUS
  5. let UsbManager = plus.android.importClass("android.hardware.usb.UsbManager");
  6. let IntentFilter = plus.android.importClass("android.content.IntentFilter");
  7. let PendingIntent = plus.android.importClass("android.app.PendingIntent");
  8. let UsbConstants = plus.android.importClass(
  9. "android.hardware.usb.UsbConstants"
  10. );
  11. let UsbInterface = plus.android.importClass(
  12. "android.hardware.usb.UsbInterface"
  13. );
  14. let Intent = plus.android.importClass("android.content.Intent");
  15. let Context = plus.android.importClass("android.content.Context");
  16. let HashMap = plus.android.importClass("java.util.HashMap");
  17. let Toast = plus.android.importClass("android.widget.Toast");
  18. let invoke = plus.android.invoke;
  19. let activity = plus.android.runtimeMainActivity();
  20. const VIDQR = 0x09c5;
  21. const VIDMY = 0x09c6;
  22. const VIDIP = 0x353d;
  23. const deviceList = [];
  24. let mPermissionIntent = null;
  25. let mUsbManager = null;
  26. let currentDevice = null;
  27. let mUsbDeviceConnection = null;
  28. let mUsbInterface = null;
  29. let mUsbEndpointIn = null;
  30. let mUsbEndpointOut = null;
  31. let usbStatusReceiver = null; //usb状态监听广播
  32. let isOpen = false;
  33. //#endif
  34. /**
  35. * 构造对象
  36. */
  37. var usbTool = {
  38. state: {
  39. USBState: "",
  40. readThreadState: false, //数据读取线程状态
  41. },
  42. options: {
  43. /**
  44. * 监听USB状态回调
  45. * @param {String} state
  46. */
  47. listenUSBStatusCallback: function (state) {},
  48. /**
  49. * 接收到数据回调
  50. * @param {Array} dataByteArr
  51. */
  52. readDataCallback: function (dataByteArr) {},
  53. },
  54. init(setOptions) {
  55. Object.assign(this.options, setOptions);
  56. this.listenUsbStatus();
  57. mUsbManager = activity.getSystemService(Context.USB_SERVICE);
  58. mPermissionIntent = PendingIntent.getBroadcast(
  59. activity,
  60. 0,
  61. new Intent("com.application.usbhost.USB_PERMISSION"),
  62. PendingIntent.FLAG_IMMUTABLE
  63. );
  64. },
  65. shortToast(msg) {
  66. Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
  67. },
  68. // 打开设备
  69. async openUsb() {
  70. let mDevices = new HashMap();
  71. mDevices = mUsbManager.getDeviceList();
  72. if (mDevices === null) return false;
  73. const devicesSize = invoke(mDevices, "size"); //获取几个长度
  74. if (devicesSize === 0) return false;
  75. const values = invoke(mDevices, "values");
  76. const iterator = invoke(values, "iterator");
  77. while (invoke(iterator, "hasNext")) {
  78. const device = invoke(iterator, "next");
  79. const vendorId = invoke(device, "getVendorId"); // 获取vendorId
  80. if (vendorId == VIDQR || vendorId == VIDMY || vendorId == VIDIP) {
  81. currentDevice = device;
  82. if (!mUsbManager.hasPermission(currentDevice)) {
  83. // 获取权限弹框
  84. mUsbManager.requestPermission(currentDevice, mPermissionIntent);
  85. for (let i = 10; i > 0; i--) {
  86. await this.delay(1000);
  87. if (i == 1 && !mUsbManager.hasPermission(currentDevice)) {
  88. return false;
  89. }
  90. if (mUsbManager.hasPermission(currentDevice)) {
  91. break;
  92. }
  93. }
  94. }
  95. if (
  96. this.initCommunication(currentDevice, UsbConstants.USB_CLASS_PRINTER)
  97. ) {
  98. return true;
  99. }
  100. }
  101. }
  102. return false;
  103. },
  104. delay(ms) {
  105. return new Promise((resolve) => setTimeout(resolve, ms));
  106. },
  107. initCommunication(device, type) {
  108. const interfaceCount = invoke(device, "getInterfaceCount"); //获取接口数量
  109. for (
  110. let interfaceIndex = 0;
  111. interfaceIndex < interfaceCount;
  112. interfaceIndex++
  113. ) {
  114. const usbInterface = invoke(device, "getInterface", interfaceIndex); // 遍历获取接口
  115. const interfaceClass = invoke(usbInterface, "getInterfaceClass");
  116. if (type != interfaceClass) {
  117. continue;
  118. }
  119. mUsbInterface = usbInterface;
  120. for (let i = 0; i < invoke(usbInterface, "getEndpointCount"); i++) {
  121. const ep = invoke(usbInterface, "getEndpoint", i);
  122. if (invoke(ep, "getType") == UsbConstants.USB_ENDPOINT_XFER_BULK) {
  123. if (invoke(ep, "getDirection") == UsbConstants.USB_DIR_OUT) {
  124. mUsbEndpointOut = ep;
  125. } else if (invoke(ep, "getDirection") == UsbConstants.USB_DIR_IN) {
  126. mUsbEndpointIn = ep;
  127. }
  128. }
  129. }
  130. if (null == mUsbEndpointIn || null == mUsbEndpointOut) {
  131. mUsbEndpointIn = null;
  132. mUsbEndpointOut = null;
  133. isOpen = false;
  134. return false;
  135. } else {
  136. if (!mUsbManager.hasPermission(currentDevice)) {
  137. isOpen = false;
  138. return false;
  139. } else {
  140. isOpen = true;
  141. return true;
  142. }
  143. }
  144. }
  145. return false;
  146. },
  147. /**
  148. * usb状态监听
  149. * @param {Activity} activity
  150. */
  151. listenUsbStatus() {
  152. if (usbStatusReceiver != null) {
  153. try {
  154. activity.unregisterReceiver(usbStatusReceiver);
  155. } catch (e) {
  156. console.error(e);
  157. }
  158. usbStatusReceiver = null;
  159. }
  160. usbStatusReceiver = plus.android.implements(
  161. "io.dcloud.android.content.BroadcastReceiver",
  162. {
  163. onReceive: (context, intent) => {
  164. plus.android.importClass(context);
  165. plus.android.importClass(intent);
  166. let action = intent.getAction();
  167. switch (action) {
  168. case UsbManager.ACTION_USB_DEVICE_ATTACHED:
  169. this.options.listenUSBStatusCallback &&
  170. this.options.listenUSBStatusCallback(
  171. "ACTION_USB_DEVICE_ATTACHED"
  172. );
  173. break;
  174. case UsbManager.ACTION_USB_DEVICE_DETACHED:
  175. isOpen = false;
  176. this.options.listenUSBStatusCallback &&
  177. this.options.listenUSBStatusCallback(
  178. "ACTION_USB_DEVICE_DETACHED"
  179. );
  180. break;
  181. }
  182. },
  183. }
  184. );
  185. let filter = new IntentFilter();
  186. filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
  187. filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
  188. activity.registerReceiver(usbStatusReceiver, filter);
  189. },
  190. /**
  191. * 关闭usb
  192. */
  193. closeUsb() {
  194. mUsbEndpointIn = null;
  195. mUsbEndpointOut = null;
  196. if (mUsbDeviceConnection != null) {
  197. mUsbDeviceConnection.releaseInterface(mUsbInterface);
  198. mUsbDeviceConnection.close();
  199. mUsbDeviceConnection = null;
  200. isOpen = false;
  201. }
  202. },
  203. /**
  204. * 获得usb打开状态
  205. *
  206. * @return true:USB打开 false:USB关闭
  207. */
  208. isOpened() {
  209. return isOpen;
  210. },
  211. sendByteData(byteData) {
  212. if (currentDevice == null) {
  213. console.log("未检测到打印机设备");
  214. return false;
  215. }
  216. if (mUsbDeviceConnection == null) {
  217. mUsbManager.requestPermission(currentDevice, mPermissionIntent);
  218. mUsbDeviceConnection = mUsbManager.openDevice(currentDevice);
  219. const ret = invoke(
  220. mUsbDeviceConnection,
  221. "claimInterface",
  222. mUsbInterface,
  223. true
  224. );
  225. }
  226. if (mUsbEndpointOut == null) {
  227. return false;
  228. }
  229. const result = invoke(
  230. mUsbDeviceConnection,
  231. "bulkTransfer",
  232. mUsbEndpointOut,
  233. byteData,
  234. byteData.length,
  235. 1500
  236. );
  237. if (result == -1) {
  238. return false;
  239. } else {
  240. return true;
  241. }
  242. },
  243. };
  244. module.exports = usbTool;