Hace ya algunos años publiqué un plugin para impresoras térmicas en Android y recientemente lo he actualizado, así que vengo a anunciar su nueva versión y enlace de descarga.

Este plugin funciona solamente en Android con impresoras térmicas que usan el protocolo ESC POS a través de Bluetooth.

Notas de la versión

Realmente es una nueva versión, no una continuación del anterior. El plugin hace lo mismo, pero los puntos más importantes son:

  • He incluido el algoritmo dithering directamente en el plugin
  • Se soporta el algoritmo Raster bit image, Bit image column format y NV graphics. Es decir, los 3 algoritmos más comunes
  • Quitada la restricción de que el ancho de imágenes debía ser múltiplo de 8
  • Ahora se crea un servicio Android para que el plugin se mantenga siempre en segundo plano
  • La API del plugin es compatible con la API HTTP ESC POS Desktop excepto por la lista de impresoras y la impresión de HTML
  • Implementado el método Beep y BeepAndAlarm para hacer ruido con la impresora
  • Está programada con Kotlin y ya no con Dart usando Flutter

Descarga

Descarga la aplicación Android en el siguiente enlace: https://parzibyte.me/static/HTTP2ESCPOSBT2.0.apk

Es tu responsabilidad conservar e instalar el archivo. A veces los navegadores y sistemas operativos bloquean el archivo

Cosas que debes saber

Este post asume que ya has vinculado tu impresora previamente. Si no lo has hecho entonces ve a la guía publicada anteriormente

Mi impresora no aparece en la lista

Si tú conoces la MAC de tu impresora entonces no es necesario que obtengas la lista de impresoras. Esto no quita que estás obligado a vincular tu impresora previamente.

De hecho es muy recomendable que hagas este paso para que pruebes que tu impresora es compatible y para que más tarde aparezca en la lista de impresoras.

Para que tu impresora aparezca debes abrir la aplicación, darle los permisos necesarios y después tocar el botón que dice Ver impresoras disponibles.

Captura de pantalla de un dispositivo Android en donde se muestra la aplicación para conectar a impresoras térmicas Bluetooth con ESC POS. Se aprecia la descripción de la aplicación y un botón para ver las impresoras disponibles

Eso te llevará a un listado de dispositivos Bluetooth. Este paso es crucial pues aquí te darás cuenta si has vinculado tu impresora correctamente y si es compatible con el plugin además de que a partir de este listado se estará armando la lista de impresoras.

Cuando aparezca tu impresora toca el botón que dice Probar.

Captura de pantalla de un dispositivo Android en donde se muestra la aplicación para conectar a impresoras térmicas Bluetooth con ESC POS. Se aprecia un listado de impresoras térmicas con su nombre y dirección MAC acompañadas de un botón para Probar

Y te debe imprimir un ticket como el siguiente:

Impresora térmica Bluetooth con un ticket impreso. El ticket contiene el texto indicando que es un ticket de ejemplo y que si se puede leer entonces ya puede comenzar a consumir el plugin desde cualquier lenguaje de programación

Si te ha impreso ese ticket entonces el plugin es totalmente compatible con tu impresora.

Nuevo funcionamiento y API

Este plugin es totalmente compatible con la API Desktop salvo en contadas excepciones. Escucha igualmente en http://localhost:8000 y expone exactamente las mismas rutas.

Te recomiendo revisar la documentación de la API para escritorio

Funciona con cualquier lenguaje de programación que pueda hablar HTTP, incluyendo JavaScript en el navegador web.

Por ejemplo, para imprimir un Hola mundo desde JavaScript en Android:

const cargaUtil = {
  "serial": "",
  "nombreImpresora": "FF:FF:FF:FF:FF:FF",
  "operaciones": [
    {
      "nombre": "EscribirTexto",
      "argumentos": [
        "Hola impresora\n"
      ]
    }
  ]
};
const respuestaHttp = await fetch("http://localhost:8000/imprimir", {
    method: "POST",
    body: JSON.stringify(cargaUtil)
});
const respuesta = await respuestaHttp.json();
if (respuesta.ok) {
    console.log("Impreso correctamente")
} else {
    console.error("Petición ok pero error en el plugin: " + respuesta.message);
}

Lo que cambia es que ahora en lugar del nombre de la impresora debes indicar la dirección MAC Bluetooth de la misma. Solo eso.

Todo lo demás funciona igual que en la documentación del plugin para escritorio incluyendo la respuesta y el endpoint para imprimir.

¿Qué cosas de la API Desktop no son compatibles?

Como lo dije, todo es exactamente igual excepto lo siguiente.

No puedes imprimir HTML

La operación GenerarImagenAPartirDeHtmlEImprimir y GenerarImagenAPartirDePaginaWebEImprimir no están disponibles porque no he encontrado wkhtmltoimage para Android de una manera tan fácil como lo es en Windows.

No sirve reenviar ni apagar

Para el caso de Desktop se puede usar el mismo plugin para reenviar peticiones y también para detener el plugin.

En este caso Android no tiene esas rutas disponibles. Eso sí, si quisieras imprimir en red local con este plugin ya existe un proxy para imprimir en impresoras térmicas pero para detener el plugin no hay alternativas hasta este momento.

La lista de impresoras es distinta debido a la MAC

Esta lista se obtiene haciendo una petición GET a http://localhost:8000/impresoras en ambos plugins. Es la misma ruta, mismo formato JSON, pero con una diferencia.

Para el plugin Desktop la lista se ve así:

[
    "PT"
]

Es un arreglo JSON de tipo cadena. Pero para el plugin Android se ve así:

[
    {
        "name": "MTP-II",
        "mac": "86:67:7A:AC:E4:40",
        "type": "Dual"
    }
]

Es un arreglo JSON pero tiene objetos con 3 propiedades:

  • name que es el nombre de la impresora
  • mac que es la MAC de la impresora (esta es la que debes enviar al imprimir)
  • type que es simplemente el tipo de dispositivo ya sea Dual o BLE

Toma en cuenta que esta lista se puede componer de más dispositivos Bluetooth que no necesariamente son impresoras.

Esto fue hecho así porque en Desktop solo necesitamos el nombre, pero en Android es necesario conocer el nombre de la impresora (por si se lo presentamos al usuario) y también la MAC. Obligatoriamente solo es necesaria la MAC, pero lo he dejado así para que el usuario pueda elegir su impresora a través del nombre.

Entonces toma eso en cuenta al momento de desarrollar. En mi caso simplemente hago un ping al endpoint que te da la versión del plugin y a partir de ahí puedo identificar si es Desktop o Android.

Recuerda: cuando quieras imprimir envía únicamente la MAC de la impresora en el parámetro nombreImpresora. No vayas a enviar el objeto completo o el name

El diseñador todavía no es compatible

Mi diseñador de tickets para impresoras térmicas que puedes usar aquí todavía no es compatible con esta versión. Para ello debes usar la anterior.

Mantener despierto al plugin

Aunque el plugin ya crea un servicio en segundo plano, por alguna razón a veces el servidor “se duerme” si pasa mucho tiempo sin que se le haga una petición.

Una solución que se me ocurre pero que no he probado es hacer ping al servidor infinitamente.

Es decir, tener, en segundo plano, algo que esté consultando a http://localhost:8000/version, que espere a que la petición se resuelva y después vuelva a hacerla.

Un poco de historia

En los últimos meses he estado muy ocupado terminando Sublime POS 4, migrando mi sitio y actualizando mis aplicaciones.

Para poder grabar el vídeo de configurar POS Android con impresora térmica primero tuve que terminar de actualizar el plugin.

Realmente no tenía planeado actualizar el plugin. La única desventaja que yo encontraba era que a veces el mismo no se mantenía ejecutándose en segundo plano, por lo que los desarrolladores tenían que encontrar la manera de mantenerlo siempre vivo ya sea modificando el administrador de batería o los ajustes de cada dispositivo.

Incluso así yo no veía eso como razón suficiente para actualizarlo. La verdadera actualización vino cuando un cliente me solicitó modificar el plugin para hacerlo compatible con una nueva versión de Android. Era cuestión de mover solo una línea y compilar, pero aquí el problema… ya no podía compilar porque no tenía la versión de Flutter

No sé qué pasó, pero no tenía las dependencias instaladas, y al querer instalarlas no se pudo. Lo que iba a ser una simple modificación se convirtió en la reescritura total del plugin. Lo ajusté para que fuera compatible con la API antigua y se lo envié al cliente; me dijo que todo iba perfecto y entonces dejé el trabajo hasta ahí pero yo sabía que ese era el camino a seguir para actualizar el plugin.

Entonces recientemente lo actualicé, implementé el algoritmo dithering, quité las restricciones de tamaño de imágenes porque ya conozco los algoritmos de impresión de imagen y lo hice compatible con la API del plugin Desktop.

Siento que Flutter, así como Node (no se parecen mucho pero sí en cuanto a sus dependencias y versiones) son unas herramientas muy buenas pero si quieres ejecutar un proyecto un poco antiguo vas a tener que esforzarte. Al menos NPM se puede cambiar entre versiones con nvm pero no puedo hacer lo mismo con Flutter.

Mi opinión de Jetpack compose

Nunca me ha agradado la programación en Android porque se usaba Java y XML para diseñar las interfaces. Me gustó Flutter con Dart porque era otra forma de diseñar aplicaciones sin tanto layout ni inflate de XML.

Escribí la nueva versión del plugin en enero de 2025 y me dio la opción de usar Jetpack compose. Me costó un poco aprenderlo para usarlo en una app básica y realmente me gustó mucho su forma de diseñar las aplicaciones.

Si el post ha sido de tu agrado te invito a que me sigas para saber cuando haya escrito un nuevo post, haya actualizado algún sistema o publicado un nuevo software. Facebook | X | Instagram | Telegram | También estoy a tus órdenes para cualquier contratación en mi página de contacto