cd /news/artificial-intelligence/how-i-built-an-in-place-android-scre… · home topics artificial-intelligence article
[ARTICLE · art-115137] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

How I Built an In-Place Android Screen Translator with Jetpack Compose, ML Kit, and Gemini Vision

A developer built ALST (AI Live Screen Translation), an open-source Android app that translates screen content in real time and overlays the translated text directly on the original coordinates. The app uses a dual-engine architecture with Google's Gemini 3.6 Flash for single-pass vision translation and ML Kit for offline on-device translation, and it implements zero-leak memory management for continuous screen capture on Android 14+.

read4 min views1 publishedAug 29, 2026

Language barriers in mobile apps, games, and foreign media are a constant friction point. Traditional screen translation tools on Android usually force users to take manual screenshots, freeze the screen, jump between applications, or deal with rigid line-by-line OCR card overlays that block the view.

To solve this, I built ALST (AI Live Screen Translation) — an open-source, real-time Android screen translator that translates any screen content in-place and renders the translated text directly over the original screen coordinates without ever leaving your active app.

In this article, I'll walk through the system architecture, how I integrated Gemini 3.6 Flash for single-pass vision translation, and how to prevent memory leaks during continuous high-density screen capturing in Android 14+.

🏗️ High-Level System Architecture

ALST is built following Clean Architecture and MVVM/MVI design patterns. The codebase is strictly partitioned into single-responsibility modules:

core/capture: MediaProjection, VirtualDisplay, & ImageReader pipeline

core/ocr: Google ML Kit Text Recognition v2 engine

core/translator: Dual translation engine (ML Kit On-Device + Gemini Flash)

core/overlay: WindowManager floating views & Compose Canvas rendering

service: ScreenTranslatorService (Foreground) & QSTranslateTileService

data: Jetpack DataStore preferences (BYOK API keys, language options)

ui: Material 3 Glassmorphic Dashboard & Overlay UI

🧠 1. Single-Pass Vision AI vs. Traditional Chaining

In conventional translation tools, the pipeline is split into three heavy steps:

Capture screen frame -> Run local OCR -> Extract text blocks & coordinates.

Send extracted raw text to a Translation API -> Receive translated strings.

Draw text cards over the screen.

While this works, it often loses contextual meaning (e.g., in video games, manga, or slang-heavy social posts).

With ALST, when running in Cloud AI Mode, the app uses Google's Gemini 3.6 Flash Multimodal Vision API:

Raw bitmap frame buffers are sent directly to the model.

In a single pass, Gemini extracts the text, understands local context/idioms, and returns both the translated text and exact bounding box coordinates (Rect).

This dramatically improves translation quality and contextual awareness while reducing pipeline complexity.

📴 2. Dual-Engine Architecture (Cloud + 100% Offline)

Recognizing that users aren't always connected to high-speed internet, ALST implements a flexible Dual-Engine System:

Cloud Engine (Gemini 3.6 Flash): Uses the com.google.ai.client.generativeai SDK with a Bring-Your-Own-Key (BYOK) model for deep contextual translation.

On-Device Engine (Google ML Kit): Combines ML Kit Text Recognition v2 with ML Kit On-Device Translation. It operates 100% offline with sub-50ms latency and zero server dependencies.

Users can toggle seamlessly between these two engines inside the app dashboard, persisted via Jetpack DataStore Preferences.

🔋 3. Zero-Leak Memory Engineering in Android 14+

Capturing raw 1440p / 4K screen frames produces bitmaps that consume over 15MB–20MB of RAM per frame. Doing this continuously using MediaProjection and ImageReader quickly leads to OutOfMemoryError (OOM) crashes if buffer recycling isn't managed strictly.

Here is how ALST handles zero-leak memory management inside ScreenCaptureManager:

suspend fun captureSingleFrame(): Bitmap? = withContext(Dispatchers.Default) {
    val image = imageReader?.acquireLatestImage() ?: return@withContext null
    try {
        val planes = image.planes
        val buffer = planes[0].buffer
        val pixelStride = planes[0].pixelStride
        val rowStride = planes[0].rowStride
        val rowPadding = rowStride - pixelStride * screenWidth

        val bitmap = Bitmap.createBitmap(
            screenWidth + rowPadding / pixelStride,
            screenHeight,
            Bitmap.Config.ARGB_8888
        )
        bitmap.copyPixelsFromBuffer(buffer)
        Bitmap.createBitmap(bitmap, 0, 0, screenWidth, screenHeight)
    } finally {
        // CRITICAL: Always close the image buffer immediately to return it to VirtualDisplay
        image.close()
    }
}

🎯 4. In-Place Overlay & Spatial Coordinate Mapping

To render translated text boxes directly over original text without distorting the layout:

ALST creates a dynamic WindowManager view of type TYPE_APPLICATION_OVERLAY.

Coordinates returned from OCR/Gemini are scaled against physical screen density (DisplayMetrics) and system navigation/notch insets.

Using Jetpack Compose Canvas, dark translucent glassmorphic cards with rounded corners are drawn exactly over original bounding boxes, placing high-contrast translated text right where your eyes expect it.

📱 5. Deep System Integration

ALST integrates directly into Android system controls for maximum convenience:

Draggable Floating Action Button (FAB): A frosted overlay button with magnetic screen-edge snapping.

Quick Settings Tile (TileService): Allows users to trigger screen translation directly from the Android status bar pull-down menu.

Android 14/15 Compliance: Runs via a Foreground Service registered with foregroundServiceType="mediaProjection" and handles runtime permissions securely via a translucent trampoline activity.

🔒 6. Privacy First

ALST operates strictly on a Bring Your Own Key (BYOK) model:

No intermediary proxy servers.

No telemetry or user tracking.

API keys stay stored strictly inside local sandboxed DataStore storage.

Captured screen frames exist purely in volatile RAM during processing and are immediately garbage-collected.

📦 Source Code & Links

ALST is 100% free and open-source under the MIT License.

If you find the architecture interesting or useful, feel free to drop a star ⭐️ on the GitHub repository or open an issue for feature requests and discussions!

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @alst 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-i-built-an-in-pl…] indexed:0 read:4min 2026-08-29 ·