Android Booth App
Overview
Package the booth as a single Android-deliverable application that embeds the existing web application.
- A customer can install one Android app and launch directly into the booth flow.
- The embedded web app can detect that it is running inside the Android host runtime.
- Handles app launch, resume, basic offline behavior, and permission bootstrapping.
- Exposes a versioned host capability surface to the embedded app (e.g. Printer Bridges).
Flow: Android App Provisioning
- Install: Customer installs the Android booth app on the device (e.g., tablet/phone) that will run the event booth.
- Launch: The app opens directly into the photobooth runtime.
- Permissions: The runtime requests any necessary permissions (e.g., Bluetooth permissions required for printer use).
- Ready State: The embedded web app loads with native Android APIs available.
Technical Architecture
WebView Bridge
The Android app uses a JavaScript bridge to communicate between the web app and native Android code:
┌─────────────────────────────────────────────────────────────┐
│ Android App │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ WebView (PWA) │ │
│ │ - Loads PWA from Cloudflare Pages │ │
│ │ - Detects bridge via window.FrameingoBridge │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ JS Bridge (window.FrameingoBridge) │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Native Kotlin Code │ │
│ │ - Bluetooth service (ESCPOS protocol) │ │
│ │ - Image processing │ │
│ │ - Printer connection management │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Bridge Contract (packages/shared)
interface FrameingoBridge {
print(request: PrintRequest): Promise<PrintResult>;
connectPrinter(): Promise<PrinterStatus>;
disconnectPrinter(): Promise<void>;
getPrinterStatus(): Promise<PrinterStatus>;
isAvailable(): Promise<boolean>;
}
Printing Implementation
- Uses ESCPOS-ThermalPrinter-Android library for ESCPOS command generation
- Communicates via native Bluetooth (not Web Bluetooth)
- Supports image printing with configurable quantity
- Auto-connects to first paired Bluetooth printer
Project Structure
apps/mobile/
├── app/
│ ├── build.gradle.kts # Gradle build config
│ └── src/main/
│ ├── AndroidManifest.xml # Bluetooth permissions
│ ├── java/.../
│ │ └── MainActivity.kt # WebView + bridge
│ └── res/ # Android resources
└── settings.gradle.kts # Gradle settings
Deployment
The Android app is distributed via direct APK installation (not Play Store). Build with:
cd apps/mobile
./gradlew assembleDebug
APK location: app/build/outputs/apk/debug/app-debug.apk