ANNAS TRI WIDAGDO/PORTFOLIO · 2026
VOL. 01 // TECHNICAL ARCHIVE
■annastriwidagdo.me
SOFTWARE ENGINEER·FULL-STACK WEB DEVELOPER·MACHINE LEARNING ENGINEER
ENTRY 001OPENING TECHNICAL ARCHIVE00% · 01 / 01
Skip to content
■annastriwidagdo.me
  • 01Home
  • 02About
  • 03Projects
  • 04Blog●
  • 05Contact
LANGEN/ID
■annastriwidagdo.me
  • Software Engineer
  • Full-Stack Web Developer
  • Machine Learning Engineer

JAKARTA, INDONESIA · UTC+7

EMAILannastriw6@gmail.com↗ (opens in a new tab)LINKEDIN/in/annastriw↗ (opens in a new tab)GITHUB@annastriw↗ (opens in a new tab)CONTACTOpen Contact→

© 2026 Annas Tri Widagdo. Drafted in grids, shipped in code.

←Back to indexBLOG / 03
[ESSAY // 03]/Android and Hardware·3 min read

From Android Print Framework to ESC/POS

Inside a Kotlin PrintService that converts Android PDF jobs into calibrated monochrome raster data for selected 58 mm and 80 mm Bluetooth thermal printers.

Written byAnnas Tri Widagdo
  • #Kotlin
  • #Android
  • #PrintService
  • #Bluetooth
  • #ESC/POS
[01]

Connecting Android to Bluetooth Thermal Printers

Mobile point-of-sale and logistics apps often need to print receipts on compact thermal printers. Instead of requiring third-party Android apps to write custom Bluetooth code for every printer brand, Thermal Printer Service was built in Kotlin as a native Android PrintService with a PrinterDiscoverySession.

This design hooks directly into the standard Android print dialog. Whenever a user taps Print in any Android application, the document is sent to the service as a temporary PDF file, allowing our background engine to handle scaling, formatting, and Bluetooth transmission automatically.

Thermal Printer Service Android interface for printer setup and profile configuration
Native Android configuration screen managing active printer profiles, offsets, and Bluetooth pairings.
[02]

Converting PDF Pages into Thermal Dot Rasters

58 mm printable width
432 dots
80 mm printable width
576 dots
Resolution
203 DPI
Maximum write chunk
1,024 bytes

When a print job arrives, Android's PdfRenderer converts each PDF page into a high-density bitmap. Because standard document sizes do not match narrow thermal receipt paper, the service automatically trims unused whitespace, centers the text, applies custom top/bottom padding, and resizes the bitmap to the printer head width (432 dots for 58 mm rolls or 576 dots for 80 mm rolls at standard 203 DPI).

The adjusted bitmap is then transformed into a clean binary monochrome image, where every black pixel represents a heated dot on the receipt paper.

[03]

Generating ESC/POS Commands and Managing Profiles

  1. 01Android Document
  2. 02Temporary PDF File
  3. 03PdfRenderer Bitmap
  4. 04Whitespace Trim and Scale
  5. 05Monochrome Conversion
  6. 0624-Dot ESC/POS Raster
  7. 07Bluetooth Chunked Write

Thermal receipt printers do not understand complex font files; they only print black-and-white dots driven by low-level ESC/POS byte commands. The app converts the monochrome bitmap into 24-dot ESC/POS raster byte arrays in memory, organizing the lines into manageable chunks for transmission.

To support different printer models in the field, configurations are saved locally using SharedPreferences and JSON. A clean RecyclerView list allows operators to easily save and switch between printer profiles, setting Bluetooth address, paper width, density scale, auto-cut, and margin offsets.

[04]

Handling Bluetooth Connections and Background Jobs

  1. 01Check Bluetooth hardware availability, power state, and Android 12 or newer runtime permissions.
  2. 02Load the selected printer profile and temporary PDF payload.
  3. 03Open an RFCOMM SPP socket with a 4-step retry strategy using 0 ms, 200 ms, 500 ms, and 1,000 ms backoff delays.
  4. 04Process printing in a background single-thread executor with CancellationToken support to keep the Android UI smooth.
  5. 05Stream ESC/POS data in chunks up to 1,024 bytes and close sockets cleanly when done or canceled.
Compatibility boundary

The project documents selected Bluetooth ESC/POS workflows. It does not document a compatibility rate, support for every vendor, or a print-success benchmark.

By separating document rendering, ESC/POS byte encoding, and Bluetooth connection management into distinct components, Thermal Printer Service provides a smooth and dependable receipt printing experience for everyday Android workflows.

Related project experience

Thermal Printer Service↗
← PREVIOUS ARTICLEIntegrating Machine Learning into a Web Application
All Articles
NEXT ARTICLE →Building a Practical Speech-to-Text Pipeline with Wav2Vec2 and FFmpeg