Dev Investigation Notes

Connecting Claude Code to an Android tablet: where do you start with the voice assistant app?

This is a translated article. Read the original in Korean ↗

This is a design discussion about moving a PC voice assistant—a Windows Python program that listens for the wake word hey_jarvis, passes a sentence to claude -p, and reads the response aloud—to an Android tablet. This article records design decisions about what to build first, not an app that was actually built or tested on a tablet. The goal was to have a tablet continuously listening while docked and charging, but the questions of where to run Claude Code and what the app should handle had become tangled together.

Conclusion

The app handles only the ears and mouth (wake word, STT, TTS, and screen), while the brain that generates answers sits behind a BrainClient interface. Build the app first using MockBrain (a stand-in that echoes what it hears). Whether the brain runs in Termux on the tablet or on a PC server, the app just sends one line of text and receives one back, so the work on the ears and mouth carries over.

Next step in one sentence: Upgrade the development PC's JDK to 17 or later (currently 16), set up the Android SDK and adb, then build an app that runs with MockBrain.

What to verify yourself (things this article cannot guarantee because they are not in the record)

These are the things to check yourself before building the MockBrain app or connecting the real Claude. The session does not provide values for the items below; only the Termux values in the final table were separately checked against the official Termux wiki (RUN_COMMAND Intent).

Connecting Claude through Termux later

The setup sequence proposed in the session was Install Termux → Install Node.js → npm i -g @anthropic-ai/claude-code → Log in to claude. Login uses browser OAuth once at the start; next, check that claude -p runs on its own in Termux and measure its response time. The session only described the app↔Termux bridge (RUN_COMMAND) as “quite tricky to set up” and provided no values.

These values were checked against the official Termux wiki (RUN_COMMAND Intent). They were not tested in this session or on a physical device.

ItemValue
Termux configurationallow-external-apps=true in ~/.termux/termux.properties
App manifest<uses-permission android:name="com.termux.permission.RUN_COMMAND" />
Intentaction com.termux.RUN_COMMAND, service com.termux.app.RunCommandService, package com.termux
Required extracom.termux.RUN_COMMAND_PATH — absolute path to the file to execute
Optional extrascom.termux.RUN_COMMAND_ARGUMENTS (argument array), com.termux.RUN_COMMAND_WORKDIR (working directory), com.termux.RUN_COMMAND_BACKGROUND (whether to run in the background), com.termux.RUN_COMMAND_PENDING_INTENT (for receiving results)
Retrieving resultsstdout, stderr, and exit code from the PendingIntent result bundle (Termux v0.109 or later). See the wiki for exact key names and example code
PermissionsThe user grants the RUN_COMMAND permission in app settings. targetSdk 30 or later requires a package query declaration in the manifest

Situation

The initial plan was for the tablet to handle only the wake word, STT, and TTS, sending text to a PC and receiving an answer. That changed to “run Claude Code on the tablet itself without going through a PC.” Since Claude Code is a Node.js CLI and cannot be put into an APK, the proposal was to run it in Termux, a Linux terminal environment for Android, and have the app issue commands through the RUN_COMMAND intent.

Symptom

The issue was confusion about the architecture, not a runtime error. Someone asked, “So using Termux doesn't mean we're developing an app?” and then asked whether the app would pass input to “Claude Code running in Termux.”

Cause

Building an app that listens and speaks and connecting an answer engine were being treated as one task. Termux does not replace app development; it handles just one thing the app cannot do on its own: running Claude Code. Nor does Claude Code stay running inside it. Normally, it is simply installed; each time the app passes it a sentence, claude -p starts fresh and exits when finished. The app's microphone is what stays listening.

Fix

This was a decision about the scope of the first development phase, not an implementation. Separate the brain through an interface, use MockBrain now, and plug in TermuxBrain or HttpBrain later.

Scope of the first app: an always-on microphone Foreground Service, wake word detection, SpeechRecognizer STT, BrainClient.ask(text), TextToSpeech, and a screen showing status (대기중/듣는중/처리중 (Waiting/Listening/Processing)) and recognition/response logs.

Checklist—not yet carried out

The following is a Kotlin design sketch based on the proposal, not original implementation code. The suspend modifier and String return type are examples supplied by this article.

interface BrainClient {
    suspend fun ask(text: String): String
}

class MockBrain : BrainClient {
    override suspend fun ask(text: String): String =
        "네, 들었어요. '$text'라고 하셨네요"
}

// Replace only the implementation on this line when connecting the real engine.
val brain: BrainClient = MockBrain()

“네, 들었어요. '$text'라고 하셨네요” (“Yes, I heard you. You said '$text'.”)

Reporter's Notes — deciding to build the ears and mouth first

The design discussion has been reconstructed as a working meeting among four people. There was no reproduction on a physical device.

Jung Bada
You know that assistant on the PC that listens when you say “헤이 자비스” (“Hey Jarvis”) and answers through claude -p? I want the tablet to run it on its own. If we install Termux, Claude Code runs there, so don't we no longer need an app?
Park Doeun
What's Termux? Does installing it mean we've built an app?
Jung Haneul
What are you basing that on, Bada? Termux is just a Linux terminal app inside Android. It only runs commands. Keeping the microphone on, listening for the wake word, turning speech into text, and reading text aloud are all jobs for the app we need to build.
Jung Bada
Then we can just put Claude Code inside the app. Bundle it all together.
Jung Haneul
We can't. Claude Code is a command-line program that runs on Node.js, so it can't go into an APK. That's why we're handing just that one piece to Termux.
Park Doeun
Oh, so the app takes the voice input and passes it to Claude Code, which stays running in Termux? I thought both sides would stay on.
Jung Haneul
Half right, half wrong. Claude Code isn't running. Each time the app passes it a sentence, claude -p starts fresh and exits once the answer is ready. Only the app's microphone stays awake all the time.
Jung Bada
So the app needs a way to tell Termux, “Feed in this sentence and give me the result.” Is that what RUN_COMMAND is? Let's connect that first.
Park Dohyun
Hold on, let's look at the cost first. That connection was described as the most cumbersome part of this approach. Both the setup and the permissions are tricky.
Jung Bada
Still, isn't that the straightforward way to keep everything on the tablet? A PC server doesn't work when the PC is off.
Park Dohyun
But a PC server saves us the hassle of getting the bridge working. And from the app's perspective, it's still sending one sentence and receiving one back. If we haven't decided which way to go, let's leave that slot open.
Park Doeun
What does leaving it open mean? The app can't do anything if it doesn't get an answer.
Jung Haneul
We fill it with a fake. Put the brain behind a single interface and have MockBrain echo what it hears for now. Later, swap in TermuxBrain or HttpBrain, and the app stays the same.
Jung Bada
Fine by me. I wanted to explore the app that listens and speaks anyway. We can build an app with a fake brain and put it on the tablet.
Park Doeun
But we need to build an APK to put it there. I checked my development PC first, and it has JDK 16. No adb, Android SDK, or Gradle either.
Jung Haneul
Isn't JDK 16 enough?
Park Doeun
Apparently Android builds need 17 or later. So we can write the code right away, but we need to install the toolchain before we can put it on the tablet.
Park Dohyun
Then Bada's right that we should start with the app. That work carries over whichever way we go. On the other hand, nobody knows yet whether the wake word actually works on Android. We have to install the app to find out.
Jung Haneul
Right. The order is toolchain setup, MockBrain app, then wake word research. We can decide where Claude lives after that. As long as we leave a slot for the brain, postponing that decision won't block work on the app.