Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DroidKaigi 2026 低レイヤもKotlinにお任せ! 〜ハードウェア制御でも言語機...

Avatar for mhidaka mhidaka
September 03, 2026

DroidKaigi 2026 低レイヤもKotlinにお任せ! 〜ハードウェア制御でも言語機能を使いこなす〜

Androidアプリと現実世界のハードウェアを繋ぐ開発は、時としてレガシーで泥臭い作業を伴います。
本セッションでは店舗などで使われるUSBサーマルプリンタの制御を題材に低レイヤのハードウェア通信を、Kotlinの言語機能とJetpack Composeを使ったモダンで宣言的な開発体験に書き換える例を紹介します。

ハードウェア制御プロトコルの多くは、突き詰めるとバイト列とマジックナンバーで構成されるコマンド体系です。従来の素朴な実装では接続不良、シーケンスの考慮漏れといった不具合とその解析に多くの時間を費やすことになります。

実例としてレシートの印字に使われるESC/POSコマンドの仕様から始まり、それをKotlin DSLで型安全にラップする手法、最後にCompose UIでのオフスクリーンレンダリングを通じたテスタブルな環境づくりという現代のアプリ開発のテクニックを駆使します。

Avatar for mhidaka

mhidaka

September 03, 2026

More Decks by mhidaka

Other Decks in Programming

Transcript

  1. Overview / 概要 Modernizing legacy hardware communication into a modern

    development experience. Achieving type-safe and robust control over complex protocols. Proposing an easily testable, modern prototyping approach utilizing Compose UI. レガシーなハードウェア通信をモダンな開発体験へと刷新。複雑なプロトコルを型安全 で堅牢な制御を実現。Compose UIを活用した、テストが容易でモダンなプロトタイピン グ手法の提示。 3
  2. Table of Contents / 目次 Part 1. ハードウェアの理解 Part 2.

    ドメインのモデリング Part 3. アプリでの低レイヤ通信 Part 4. モダンな開発環境 4
  3. Understanding Hardware ハードウェアの理解 • Hardware Requirements • Organizing Constraints •

    Hints for App Design • ハードウェア要件 • 制約の整理 • アプリ設計の手がかり 5
  4. SII MP-B20 / セイコーインスツルメンツ社 MP-B20 A leading mobile printer in

    Japan featuring a thermal line dot printing method. It supports both USB and Bluetooth connectivity and comes equipped with Japanese fonts. 国内の代表的なモバイルプリンタ。感熱ラインドット方式 のサーマルプリンタ。USB・Bluetooth接続方法に対応 しているほか日本語フォントを搭載。 6
  5. Differences in Hardware Specs / 機材スペックの違い Protocols, voltages, and connection

    methods are completely independent of the Android device and are not always optimized for mobile use. プロトコル・電圧・接続方法・すべてがAndroidデバイス とは独立で、モバイルむけに最適化されているわけでは ない 8
  6. Constraints on Functionality / 機能に対する制約条件 1 2 3 Constraints become

    stricter towards the bottom. 1. 2. 3. Hardware Physical & Spec Constraints Android OS Connectivity & API Requirements App Maintainability & Productivity 上から下に向かって従うべきルール・制約が強くなる 1. 2. 3. ハードウェアが持つ特性 Android OSでの実現・接続性 開発環境の生産性や保守性の確保 10
  7. ESC/POS Protocol A proprietary command system developed by Seiko Epson

    to control POS printers and customer displays. Normally, these commands are abstracted and completely hidden by device drivers. セイコーエプソンが開発したPOSプリンタ(レシートプリンタ)やカスタ マーディスプレイを制御するための独自のコマンド体系(プリンタ制御 言語)。本来であればデバイスドライバが隠蔽し、見えなくしてくれる。 11
  8. ESC/POS Protocol - Assembling the Bytes / バイト列の組立 bash -

    escpos_send Init with 0x1B 0x40... Center with 0x1B 0x61 0x01... # Send ESC/POS commands to printer Let's see... okay, Just gonna fire off 0x1B 0x40 0x1B 0x61 0x01 ! $ send_bytes 0x1B 0x61 0x01 >> Align Center Enabled $ send_bytes 0x1B 0x40 >> Printer Initialized # Combined sequence: $ sending: 0x1B 0x40 0x1B 0x61 0x01 >> Transmission complete (5 bytes) 12
  9. • Kotlin DSL • Language Support • Hardware Abstraction •

    Kotlin DSL • 言語によるサポート • ハードウェアの抽象化 Domain Modeling ドメインモデリング 13
  10. Kotlin DSL(Domain-Specific Language) DSL: A language specialized for a specific

    domain. Kotlin DSL: Building expressive, domain-specific APIs using Kotlin's built-in language features, without the need for an independent parser. DSL(ドメイン固有言語)とは特定の用途や領域に特化したプログラミング 言語のこと。独立した構文と処理系をもつこともありますが、Kotlin DSL の場合はKotlin言語の言語機能を使って特定のドメインに特化した表現 力豊かなAPIを構築することを意味しています。 14
  11. Expressing the Domain / ドメインを表現する Command Bytes (Hex) Description ESC

    @ 0x1B 0x40 Initialize printer / プリンタの初期化 ESC a n 0x1B 0x61 n Alignment n=0x00: Left, 0x01: Center, 0x02: Right GS ! n 0x1D 0x21 n Set character size (e.g., double-width/height) 文字サイズ指定 (倍角など) LF 0x0A Print and line feed / 改行および印字 GS V m 0x1D 0x56 m Cut paper / 用紙カット 15
  12. Expressing the Domain / ドメインを表現する Direct byte manipulation (Center alignment

    and printing "Receipt") バイト列による直接制御を行う場合 17
  13. Intermediate Step / 途中経過 Defining the base interface to hold

    a byte array 基底インターフェイスを作成。バイト列を持つことを定義 18
  14. Language Features for Type-Safe Builders Type-Safe Buildersを実現する言語機能 Higher-Order Functions 高階関数

    Function Literals with Receiver レシーバ付き 関数リテラル Extension Functions 拡張関数 23
  15. Higher-Order Functions and Trailing Lambdas 高階関数とトレーリングラムダ In Kotlin, you can

    define Higher-Order Functions, which are functions that take other functions as parameters. If the last parameter is a function, the "trailing lambda" rule allows you to place the lambda expression outside the parentheses. Kotlinでは関数を引数に取る関数(高階関数)を定義できますが最後の引数が関数である場合、そのラ ムダ式を括弧の外に出せるルール(トレーリングラムダ)があります 24
  16. Summary / まとめ Structured & Declarative / 構造化と宣言的表現 Achieves high

    readability through declarative block structures. 宣言的なブロック構造により、高い可読性で表現 Context Control / コンテキストの制御 Provides only relevant methods for the current scope using function literals with receiver. レシーバ付き関数を活用し、現在の文脈(スコープ)に適切なメソッドのみを提供 Type Safety / 静的型付けによる安全性 Prevents invalid calls at compile time by leveraging Kotlin's strong type system. Kotlinの強力な型システムにより、不正な呼び出しをコンパイル時に予防
  17. Why Existing SDKs Fall Short / 既存SDKの限界 The Problem 課題

    Mismatch between imperative SDKs and modern declarative/reactive architectures (e.g., Compose, StateFlow). 命令的な既存SDKと、現代の宣言的・リアクティブな設計(ComposeやStateFlow)とのパラダイム の不一致がある。 The Solution 解決策 Bridging the gap with a custom Kotlin DSL to maximize productivity. DSLによる抽象化レイヤーを構築し、ハードウェア制御を現代のアーキテクチャに適合させる。 30
  18. Low-Level Communication in Apps • USB Host API • Data

    Transfer Characteristics アプリでの低レイヤ通信 • USB Host API • データ通信の特性 31
  19. USB Host API UsbManager A system service that manages USB

    state retrieval and device communication. USBの状態取得やデバイスとの通信を管理するシステムサービス UsbDevice A class representing a connected USB device. 接続されているUSB機器を表すクラス 34
  20. USB Host API UsbInterface A functional unit of the device

    (some USB devices have multiple functions, such as an integrated mouse and keyboard). デバイスがもつ機能単位(複数機能をもつUSBデバイスがあります。 マウスとキーボードが一体化したりします) UsbEndpoint An input/output interface for data transfer. It defines the communication direction (IN/OUT) and the transfer type, such as Bulk Transfer. データ転送の入出力インターフェイス。IN/OUTなどの方向や バルク 転送(Bulk Transfer)など方式があります 35
  21. Bulk Transfer & Stream Abstraction バルク転送とストリーム化 Advantages of Bulk Transfer

    / バルク転送のメリット • Designed for efficient, high-volume data transfer. 大量のデータを効率的に転送するために設計された方式 OutputStream Encapsulation / 低レイヤ制御を隠蔽する • Allows the app to use it simply as a standard OutputStream. アプリからは標準的なインターフェイスにみえる 36
  22. 37

  23. Thermal Printer Buffers & Print Speeds サーマルプリンタのバッファと印字速度 Hardware Characteristics /

    ハードウェア特性の考慮 Low-cost models often have severely limited buffers and bandwidth.ローコストを追求した安価なモデルは、バッファが小さく 帯域も限られる。 39
  24. Modern Development Environment モダンな開発環境 • Compose UI • Bridging the

    Gap • Maximizing Engineering • Compose UI • ギャップを埋める • エンジニアリング最大化 40
  25. Synergy of Kotlin DSL & Compose UI Declarative Tree Structures

    Both are declarative and build hierarchical data structures (UI Tree vs. Command List) based on state. 宣言的な木構造 どちらもデータ状態に基づき、宣言的にツリー構造(UIツリーとコマ ンドリスト)を構築する。 44
  26. Synergy of Kotlin DSL & Compose UI Seamless UI Mapping

    Because of their structural similarity, mapping DSL commands to Compose components enables perfect print previews in Android Studio. UIへのシームレスな変換 構造が似ているため、DSLのコマンド群をCompose UIにマッピングす るだけで、Android Studio上で印刷プレビューを完全に再現できる。 45
  27. Synergy of Kotlin DSL & Compose UI Seamless UI Mapping

    Because of their structural similarity, mapping DSL commands to Compose components enables perfect print previews in Android Studio. UIへのシームレスな変換 構造が似ているため、DSLのコマンド群をCompose UIにマッピングす るだけで、Android Studio上で印刷プレビューを完全に再現できる。 46
  28. 47

  29. Font Availability / 搭載フォントの依存 Printer memory and region dictate available

    built-in fonts. 機種のメモリ容量や販売地域による内蔵フォントセットのばらつき Character Encoding / 文字コードと文字化け Limited character support compared to Android apps causes garbled text (Tohu). プリンタ側はアプリより扱える文字種が少なく、文字化けが発生するリスク Feature Fragmentation / 拡張機能の断片化 Barcode/2D code commands vary by model, with some lacking support entirely. バーコード等のコマンド差異や、未対応機種への個別対応コスト
  30. Off-Screen Rendering with Compose Runtime オフスクリーンレンダリングの実現 Three Phases of Rendering

    Manually reproducing the Composition, Layout, and Drawing phases for custom rendering tasks (e.g., generating print bitmaps). Composition、Layout、Drawingの3つのフェーズをコード側で制御し、オフスク リーン上で描画を完結させる。 ComposeView in Android View Hierarchy Injecting a ComposeView into an off-screen view hierarchy with View.INVISIBLE to trigger Composition without displaying it to the user. 画面に表示させない( INVISIBLE)状態でView階層にアタッチし、ユーザーに見せ ないままComposeのライフサイクルを駆動する。 52
  31. 53

  32. General Printer class / 汎用プリンターの作成 Overcoming Language Barriers Converting print

    commands into an image before sending via ESC/POS-compliant commands, solving font and character encoding issues for non-Japanese supported thermal printers. プリンターアーキテクチャを汎用に 日本語未対応のプリンタに対し、印刷コマンドを一旦画像化してESC/POS 準拠のコマンド経由で送信し、文字化けやフォント依存の課題をクリアする。 55
  33. Wrap-up / まとめ • Kotlin DSL & Productivity • 宣言的なDSLによる生産性

    • Hardware-Specific Low-Level • ハードウェア特性 Control • モダンな開発環境の転用 • Feature Expansion via Modern UI Kotlin has the power to transform legacy into modern development. Kotlinにはレガシーシステムをモダンに変える力がある