• 首页
  • 栏目
  • ERP
  • 安卓开发实现获取扫码枪扫码二维码、条形码后的内容

安卓开发实现获取扫码枪扫码二维码、条形码后的内容

  • 2021-12-28
  • Admin

扫码枪是如何工作的,安卓如何怎么获取扫码枪的内容。本文将介绍安卓获取和处理商米收银机扫码枪扫描后的内容。包括:“安卓开发获取扫码枪扫描后的内容”、“处理扫码枪扫描后的内容”、“在Fragment中使用ScanGun类”。

1、安卓开发获取扫码枪扫描后的内容。

扫码枪会将扫描出来的内容转化为键盘事件KeyEvent,所以我们在fragment类中重写onKeyDownChild方法,就可以捕获扫码事件,进而获取扫码内容:

  1. public void onKeyDownChild(int keyCode, KeyEvent event) {
  2. log.info("---------------------------------onKeyDown: KeyCode:" + keyCode + "------event:" + event + "------------------------------------");
  3. scanGun.isMaybeScanning(keyCode, event);
  4. }

2、处理扫码枪扫描后的内容。

SanGun类定义一个isMayBeScanning方法,扫码枪扫描后触发键盘事件,在键盘事件中调用isMayBeScanning方法,进而解析获取扫码内容:

查看代码
  1. package com.bx.erp.helper;
  2. import android.view.KeyEvent;
  3. import org.apache.log4j.Logger;
  4. public class ScanGun {
  5. private Logger log = Logger.getLogger(this.getClass());
  6. /**
  7. * 默认按键之间时间间隔
  8. */
  9. public final static int MAX_KEYS_INTERVAL_DEFAULT = 200;
  10. private long currentTime = 0;
  11. private boolean isKeySHIFT = false;
  12. private StringBuilder stringBuilder = new StringBuilder();
  13. private ScanGunCallBack callBack = null;
  14. private static int maxKeysInterval = MAX_KEYS_INTERVAL_DEFAULT;
  15. /**
  16. * 设置按键事件的最大时间间隔(部分扫描枪稍大,建议范围20--100)
  17. *
  18. * @param interval 时间间隔
  19. */
  20. public static void setMaxKeysInterval(int interval) {
  21. maxKeysInterval = interval;
  22. }
  23. public ScanGun(ScanGunCallBack callBack) {
  24. this.callBack = callBack;
  25. }
  26. public ScanGun() {}
  27. public boolean isMaybeScanning(int keyCode, KeyEvent event) {
  28. log.info("isMaybeScanning--");
  29. log.info("event.getFlags:" + event.getFlags());
  30. if (event.getFlags() != 0x8 && event.getFlags() != 0x6) {
  31. return false;
  32. }
  33. if (currentTime == 0) {
  34. if (stringBuilder.length() > 0) {
  35. stringBuilder = stringBuilder.delete(0, stringBuilder.length());
  36. }
  37. currentTime = System.currentTimeMillis();
  38. } else {
  39. if ((System.currentTimeMillis() - currentTime) > maxKeysInterval) {
  40. if (stringBuilder.length() > 0) {
  41. stringBuilder = stringBuilder.delete(0,
  42. stringBuilder.length());
  43. }
  44. }
  45. currentTime = System.currentTimeMillis();
  46. }
  47. // Shift
  48. if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {
  49. if (event.getAction() == KeyEvent.ACTION_DOWN) {
  50. //按着shift键,表示大写
  51. isKeySHIFT = true;
  52. } else {
  53. //松开shift键,表示小写
  54. isKeySHIFT = false;
  55. }
  56. }
  57. // Enter
  58. if (keyCode == KeyEvent.KEYCODE_ENTER) {
  59. isKeySHIFT = false;
  60. currentTime = 0;
  61. if (callBack != null) {
  62. log.info("stringBuilder:" + stringBuilder);
  63. callBack.onScanFinish(stringBuilder.toString());
  64. }
  65. return true;
  66. }
  67. if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
  68. // 数字键(键盘上方横条数字,需要考虑Shift)
  69. handleTopNumKeys(keyCode);
  70. } else if (keyCode >= 29 && keyCode <= 54) {
  71. // 字母键(需要考虑Shift)ww
  72. checkShift((char) (keyCode + 68), (char) (keyCode + 36));
  73. } else if (keyCode >= 144 && keyCode <= 158) {
  74. // 数字键盘区
  75. handleNumPadKeys(keyCode);
  76. log.info("数字:" + stringBuilder);
  77. } else {
  78. // 键盘主键区其他双字符键位
  79. switch (keyCode) {
  80. case KeyEvent.KEYCODE_GRAVE: {
  81. checkShift(ASCII.CHAR_SIGN_BACKTICK, ASCII.CHAR_SIGN_TILDE);
  82. break;
  83. }
  84. case KeyEvent.KEYCODE_MINUS: {
  85. checkShift(ASCII.CHAR_SIGN_MINUS, ASCII.CHAR_SIGN_UNDERSCORE);
  86. break;
  87. }
  88. case KeyEvent.KEYCODE_EQUALS: {
  89. checkShift(ASCII.CHAR_SIGN_EQUALS, ASCII.CHAR_SIGN_PLUS);
  90. break;
  91. }
  92. case KeyEvent.KEYCODE_LEFT_BRACKET: {
  93. checkShift(ASCII.CHAR_SIGN_BRACKET_LEFT,
  94. ASCII.CHAR_SIGN_BRACE_LEFT);
  95. break;
  96. }
  97. case KeyEvent.KEYCODE_RIGHT_BRACKET: {
  98. checkShift(ASCII.CHAR_SIGN_BRACKET_RIGHT,
  99. ASCII.CHAR_SIGN_BRACE_RIGHT);
  100. break;
  101. }
  102. case KeyEvent.KEYCODE_BACKSLASH: {
  103. checkShift(ASCII.CHAR_SIGN_BACKSLASH, ASCII.CHAR_SIGN_BAR);
  104. break;
  105. }
  106. case KeyEvent.KEYCODE_SEMICOLON: {
  107. checkShift(ASCII.CHAR_SIGN_SEMICOLON, ASCII.CHAR_SIGN_COLON);
  108. break;
  109. }
  110. case KeyEvent.KEYCODE_APOSTROPHE: {
  111. checkShift(ASCII.CHAR_SIGN_QUOTE, ASCII.CHAR_SIGN_DOUBLE_QUOTE);
  112. break;
  113. }
  114. case KeyEvent.KEYCODE_COMMA: {
  115. checkShift(ASCII.CHAR_SIGN_COMMA, ASCII.CHAR_SIGN_LESS);
  116. break;
  117. }
  118. case KeyEvent.KEYCODE_PERIOD: {
  119. checkShift(ASCII.CHAR_SIGN_PERIOD, ASCII.CHAR_SIGN_GREATER);
  120. break;
  121. }
  122. case KeyEvent.KEYCODE_SLASH: {
  123. checkShift(ASCII.CHAR_SIGN_SLASH, ASCII.CHAR_SIGN_QUESTION);
  124. break;
  125. }
  126. // 其他单字符键位
  127. case KeyEvent.KEYCODE_SPACE: {
  128. stringBuilder.append(ASCII.CHAR_SIGN_SPACE);
  129. log.info("Other StringBuilder:" + stringBuilder);
  130. break;
  131. }
  132. default: {
  133. return false;
  134. }
  135. }
  136. return true;
  137. }
  138. return true;
  139. }
  140. /**
  141. * 判断是否同时按下Shift键
  142. *
  143. * @param ascallNoShift
  144. * @param ascallOnShift
  145. */
  146. private void checkShift(char ascallNoShift, char ascallOnShift) {
  147. if (isKeySHIFT) {
  148. stringBuilder.append(ascallOnShift);
  149. isKeySHIFT = false;
  150. } else {
  151. stringBuilder.append(ascallNoShift);
  152. }
  153. }
  154. /**
  155. * 数字键盘区按键
  156. *
  157. * @param keyCode
  158. */
  159. public void handleNumPadKeys(int keyCode) {
  160. if (keyCode <= 153) {
  161. stringBuilder.append((char) (keyCode - 96));
  162. } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_DIVIDE) {
  163. stringBuilder.append(ASCII.CHAR_SIGN_SLASH);
  164. } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_MULTIPLY) {
  165. stringBuilder.append(ASCII.CHAR_SIGN_STAR);
  166. } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_SUBTRACT) {
  167. stringBuilder.append(ASCII.CHAR_SIGN_MINUS);
  168. } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_ADD) {
  169. stringBuilder.append(ASCII.CHAR_SIGN_PLUS);
  170. } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_DOT) {
  171. stringBuilder.append(ASCII.CHAR_SIGN_PERIOD);
  172. }
  173. }
  174. /**
  175. * 键盘上方数字键
  176. *
  177. * @param keyCode
  178. */
  179. private void handleTopNumKeys(int keyCode) {
  180. if (keyCode < 7 || keyCode > 16) {
  181. return;
  182. }
  183. switch (keyCode) {
  184. case KeyEvent.KEYCODE_0:
  185. checkShift(ASCII.CHAR_NUM_0, ASCII.CHAR_SIGN_PAREN_RIGHT);
  186. break;
  187. case KeyEvent.KEYCODE_1:
  188. checkShift(ASCII.CHAR_NUM_1, ASCII.CHAR_SIGN_EXCLAM);
  189. break;
  190. case KeyEvent.KEYCODE_2:
  191. checkShift(ASCII.CHAR_NUM_2, ASCII.CHAR_SIGN_AT);
  192. break;
  193. case KeyEvent.KEYCODE_3:
  194. checkShift(ASCII.CHAR_NUM_3, ASCII.CHAR_SIGN_HASH);
  195. break;
  196. case KeyEvent.KEYCODE_4:
  197. checkShift(ASCII.CHAR_NUM_4, ASCII.CHAR_SIGN_DOLLAR);
  198. break;
  199. case KeyEvent.KEYCODE_5:
  200. checkShift(ASCII.CHAR_NUM_5, ASCII.CHAR_SIGN_PERCENT);
  201. break;
  202. case KeyEvent.KEYCODE_6:
  203. checkShift(ASCII.CHAR_NUM_6, ASCII.CHAR_SIGN_CARET);
  204. break;
  205. case KeyEvent.KEYCODE_7:
  206. checkShift(ASCII.CHAR_NUM_7, ASCII.CHAR_SIGN_AMPERSAND);
  207. break;
  208. case KeyEvent.KEYCODE_8:
  209. checkShift(ASCII.CHAR_NUM_8, ASCII.CHAR_SIGN_STAR);
  210. break;
  211. case KeyEvent.KEYCODE_9:
  212. checkShift(ASCII.CHAR_NUM_9, ASCII.CHAR_SIGN_PAREN_LEFT);
  213. break;
  214. default:
  215. break;
  216. }
  217. }
  218. public interface ScanGunCallBack {
  219. public void onScanFinish(String data);
  220. }
  221. }

3、在Fragment中使用ScanGun类。

ScanGun类定义了一个内部类接口,data就是扫描完成后的内容:

  1. public interface ScanGunCallBack {
  2. public void onScanFinish(String data);
  3. }

扫码完成后,调用该接口的onScanFinish方法:

  1. // Enter
  2. if (keyCode == KeyEvent.KEYCODE_ENTER) {
  3. isKeySHIFT = false;
  4. currentTime = 0;
  5. if (callBack != null) {
  6. log.info("stringBuilder:" + stringBuilder);
  7. callBack.onScanFinish(stringBuilder.toString());
  8. }
  9. return true;
  10. }

所以在Fragment获取扫描结果,需要创建Scan的实例,并且实现这个onScanFinish方法:

  1. /* 初始化扫码枪 */
  2. private void initScanGun() {
  3. // 设置key事件最大间隔,默认20ms,部分低端扫码枪效率低
  4. ScanGun.setMaxKeysInterval(50);
  5. scanGun = new ScanGun(new ScanGun.ScanGunCallBack() {
  6. @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
  7. @Override
  8. public void onScanFinish(String scanResult) {

联系站长

QQ:769220720

Copyright © SibooSoft All right reserved 津ICP备19011444号