Сканер штрих-кодів і Java
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Нещодавно в рамках проекту, який пишеться на Java на базі SpringBoot, виникла задача підключити сканер штрих-кодів.
Причому операційною системою, на якій виконуватиметься Java-application, є Embedded Linux.
Кожен такий сканер (ми використали виробництва Honeywell) за замовчуванням має режим «клавіатури» — USB-Keyboard simulation. Тобто коли сканер розпізнає штрих-код, то він його посилає на комп’ютер так, наче до комп’ютера підключена клавіатура і хтось ввів з неї символи розпізнаного штрих коду.
Проблема такого режиму в тому як фільтрувати контекст вводу? Адже може бути відкрите діалогове вікно, в якому не потрібно, щоб раптом прилітали символи від сканера. До того ж в Linux введення з клавіатури реєструються як події ядра Linux, з відповідним нетривіальним форматом, куди входить і тайм-стамп події, тобто кожне натискання клавіші супроводжується купою додаткової інформації. І нефільтрований Input stream такої інформації при її перегляді є набором якихось байтів, причому їх просто дофіга і оті ASCII-символи власне розпізнаного штрих-коду навіть не проглядаються.
Один з наших програмістів взявся реалізувати розбір цих event-ів від Linux, в результаті написав два окремих Java-класи з використанням BufferedInputStream. Об’єкт одного класу крутиться в своєму потоці і розбирає структуру Linux-event’у кожного сканкоду клавіші (з якимись таблицями перекодування сканкодів у ASCII), а об’єкт другого класу теж крутиться у іншому треді, слідкує за першим, щоб сформувати рядок символів коли в першому треді спорожнів input-buffer і він перейшов в стан блокування. Тоді цей другий тред вмикав прапорець, що рядок сформовано — можна забирати.
Кожен Java-клас містив десь з сотню рядків.
Програміст мучився з пошуком рішення, з тими Linux-event’ами десь тиждень.
Той код хоч і працював, але був доволі незрозумілий, з якимись часовими інтервалами в тих тредах, неочевидним обміном даними між ними. І, головне, він не гарантував коректність послідовності символів якщо кнопку сканера натиснути швидко підряд два рази.
Мене це трохи напружувало, до того ж потім той програміст звільнився.
Тоді я взяв документацію на сканер і виявилось, що сканер може працювати як в KEYBOARD-режимі, так і в режимі USB-Serial simulation, тобто як звичайний послідовний пристрій введення (в Linux він з’являється як TTY-файл). Кожен подібний сканер може бути переведений в цей режим, треба просто ним відсканувати спеціальний командний штрих-код, який присутній в документації. Причому непотрібно параметризувати якусь швидкість передачі, оці всі parity, stop-bits, etc. Потрібно лише просто прочитати з вхідного буфера ГОТОВИЙ рядок ASCII.
Після переведення сканера в цей режим кількість рядків коду на Java скоротилася до ЧОТИРЬОХ. З усіма обв’язками — десь до двадцяти для реалізації шаблону Observable, щоб натискання кнопки на сканері ВІДРАЗУ викликало потрібний код в Observer.
На написання і шліфування коду пішла десь одна година.
Виявилось, що рішення задачі отримання в Java-програмі готових ASCII-рядків зі сканеру штрих-кодів — тривіальне.
24 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів