Как мы интегрировали React Native и Bluetooth-принтер
Всем привет, меня зовут Александр, я Frontend-разработчик из веб-студии Pyrobyte. Мы работаем с одним клиентом из Казахстана: ISMET. kz. Это — платформа для бизнеса, на которой собраны современные IT-решения для предпринимателей, меры господдержки и обучающие материалы. Наш клиент обратился к нам за разработкой модуля кассы (напоминают наши российские кассовые аппараты). В этой статье расскажу, как мы выполнили задачу.
О Bluetooth-принтере
Эта касса нужна, чтобы совершать торговые операции через приложение на смартфоне, так как в Казахстане нет необходимости в оборудовании с криптографией. Отсюда и потребность в печати чека для клиента. Необходимо обеспечить возможность печати из мобильного приложения с помощью Bluetooth принтера для чеков.
Мы получили принтер для печати чеков и приступили к тестированию задач. Большая часть задач легла на меня, на Frontend-разработчика, так как необходимо написать прослойку для стека технологий, на котором разрабатывается приложение, и для ПО присланного принтера.
Шаги интеграции с примерами
Входные ресурсы:
- разработанный модуль “кассового аппарата” для уже имеющегося приложения на React Native версии 0.63.4 (далее RN)
- Bluetooth принтер Rongta RPP300
- SDK от вендора принтера для Android, iOS на Java и Objective-c соответственно
Мы пишем приложение на RN, поэтому SDK, который получили от вендора, без определенной обёртки (Native Modules) не получится в нем использовать.
Соответственно основной задачей стояло сделать интеграцию SDK в RN приложение.
Основные шаги по написанию Native Modules здесь описываться не будут, потому что существует документация, и процесс может изменяться и отличаться для разных версий RN.
В нашем случае использовался Bluetooth принтер (характеристики можно посмотреть по ссылке выше), поэтому первым делом нам нужно было организовать подключение к принтеру из нашего приложения.
Для этого требуется несколько методов (примеры ниже приведены для Java):
- проверка, включен ли Bluetooth
- включение Bluetooth (если отключен)
- получение списка доступных устройств
- выбор устройства
- подключение к устройству (принтеру)
P. S. Не опираться как на истинность, приведены в качестве примера для статьи и не являются копией методов реального проекта по понятным причинам. Не для использования в production.
1. Проверка, включен ли Bluetooth
2. Включение Bluetooth
3. Получение списка доступных устройств
4. Выбор устройства
Далее необходимо подключить в зависимости .jar файл от вендора принтера, в котором реализуются основные классы по работе с низкоуровневыми командами для печати.
Или же можно перетащить файл в папку libs для вашего проекта и далее следовать инструкции, которую предлагает Android Studio. Другие способы подключения можно поискать на просторах сети.
5. Подключение к устройству
Добавлю, что в реальном приложении необходимо более грамотно\полно реализовать работу с Bluetooth, написать сканирование устройств, так как в реализации-примере этого нет, и придется полагаться на текущие методы, которые подойдут в рамках примера.
Реализацию UI в RN описывать не будем, из-за этого статья станет слишком большой.
Ниже приведу пример части интерфейса на стороне JavaScript:
Теперь реализуем класс печати изображения. Bluetooth принтеры могут быть различных моделей и с разным типом команд соответственно (зависит от аппаратной части). Поэтому всё должно быть реализовано на фабриках, некоторые из них предоставляются из SDK вендора (они реализуют процесс печати, положение каретки и т.п.).
Для данной модели использовались ESC команды (пример спецификации). Приведу небольшой пример только для этого вида команд в Java\JavaScript.
Из JS части мы делаем захват view чека. В нативную часть приложения нам необходимо передать URI. Для захвата (скриншота) view, можно использовать этот пакет, например.
Посмотрим на метод создания bitmap, он необходим нам для того, чтобы его передать на принтер для печати.
Теперь метод, который непосредственно отправляет команды на печать (Взято из документации к SDK).
Далее вызывающий метод, который доступен из JS:
На этом краткая история заканчивается. Результат: артефакты на бумаге, неудачные попытки печати, а другой бумаги не было:)
Делитесь в комментариях своим опытом интеграций, все обсудим :)