Как мы интегрировали React Native и Bluetooth-принтер

Всем привет, меня зовут Александр, я Frontend-разработчик из веб-студии Pyrobyte. Мы работаем с одним клиентом из Казахстана: ISMET. kz. Это — платформа для бизнеса, на которой собраны современные IT-решения для предпринимателей, меры господдержки и обучающие материалы. Наш клиент обратился к нам за разработкой модуля кассы (напоминают наши российские кассовые аппараты). В этой статье расскажу, как мы выполнили задачу.

Как мы интегрировали React Native и Bluetooth-принтер

О 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

Рисунок 1 - Метод checkEnabledBluetooth
Рисунок 1 - Метод checkEnabledBluetooth

2. Включение Bluetooth

Рисунок 2 - Метод requestEnabledBluetooth
Рисунок 2 - Метод requestEnabledBluetooth

3. Получение списка доступных устройств

Рисунок 3 - Метод getListBluetoothDevices
Рисунок 3 - Метод getListBluetoothDevices

4. Выбор устройства

Рисунок 4 - Метод selectBluetoothDevice
Рисунок 4 - Метод selectBluetoothDevice

Далее необходимо подключить в зависимости .jar файл от вендора принтера, в котором реализуются основные классы по работе с низкоуровневыми командами для печати.

Рисунок 5 - Пример подключения .jar файла
Рисунок 5 - Пример подключения .jar файла

Или же можно перетащить файл в папку libs для вашего проекта и далее следовать инструкции, которую предлагает Android Studio. Другие способы подключения можно поискать на просторах сети.

5. Подключение к устройству

Рисунок 6 - Метод connectViaBluetooth
Рисунок 6 - Метод connectViaBluetooth

Добавлю, что в реальном приложении необходимо более грамотно\полно реализовать работу с Bluetooth, написать сканирование устройств, так как в реализации-примере этого нет, и придется полагаться на текущие методы, которые подойдут в рамках примера.

Реализацию UI в RN описывать не будем, из-за этого статья станет слишком большой.

Ниже приведу пример части интерфейса на стороне JavaScript:

Рисунок 7 - Интерфейс по работе с Native Module в JS
Рисунок 7 - Интерфейс по работе с Native Module в JS

Теперь реализуем класс печати изображения. Bluetooth принтеры могут быть различных моделей и с разным типом команд соответственно (зависит от аппаратной части). Поэтому всё должно быть реализовано на фабриках, некоторые из них предоставляются из SDK вендора (они реализуют процесс печати, положение каретки и т.п.).

Для данной модели использовались ESC команды (пример спецификации). Приведу небольшой пример только для этого вида команд в Java\JavaScript.

Из JS части мы делаем захват view чека. В нативную часть приложения нам необходимо передать URI. Для захвата (скриншота) view, можно использовать этот пакет, например.

Посмотрим на метод создания bitmap, он необходим нам для того, чтобы его передать на принтер для печати.

Рисунок 8 - Метод создания bitmap из URI
Рисунок 8 - Метод создания bitmap из URI

Теперь метод, который непосредственно отправляет команды на печать (Взято из документации к SDK).

Рисунок 9 - Метод печати через ESC команды
Рисунок 9 - Метод печати через ESC команды

Далее вызывающий метод, который доступен из JS:

Рисунок 10 - Вызывающий метод печати
Рисунок 10 - Вызывающий метод печати

На этом краткая история заканчивается. Результат: артефакты на бумаге, неудачные попытки печати, а другой бумаги не было:)

Рисунок 11 - Результат
Рисунок 11 - Результат

Делитесь в комментариях своим опытом интеграций, все обсудим :)

11
Начать дискуссию