OpenVoiceIME is an Android voice input method editor (IME) that records speech locally, sends the audio to an OpenAI-compatible transcription endpoint, and inserts the returned text into the focused app.
It is meant for people who want a configurable voice keyboard instead of a fixed vendor keyboard, and for developers who want a small Android IME codebase to extend with other speech-to-text providers.
Portable ASR is a self-hosted OpenAI-compatible transcription server. OpenVoiceIME can use it as a custom provider by setting the server base URL, token, model, and language in settings.
- Android users who want voice typing through OpenAI, Groq, or a compatible self-hosted transcription server.
- Self-hosters who already expose an OpenAI-compatible
/v1/audio/transcriptionsendpoint. - Android developers who want to add provider adapters, improve IME behavior, or use this as a reference for remote speech-to-text input.
OpenVoiceIME is early project software. It supports manual installation, configuration, and testing through the published APK, GitHub Releases, or local builds.
Supported today:
- Android IME service for recording, uploading, and inserting transcribed text.
- Settings screen for provider URL, model, token, language, custom presets, and insertion behavior.
- OpenAI-compatible multipart transcription requests.
- Built-in presets for OpenAI and Groq.
- Local response-time metrics and basic network diagnostics.
Not supported yet:
- Provider-specific adapters for Deepgram, AssemblyAI, Google Speech-to-Text, or Azure Speech.
- End-to-end Android instrumented tests.
- The OpenVoiceIME keyboard starts a local microphone recording.
- The recording is sent as multipart audio to
{baseUrl}/v1/audio/transcriptions. - The configured provider returns a JSON response with a
textfield. - OpenVoiceIME commits the text into the active input field.
By default, OpenVoiceIME uses https://api.openai.com with gpt-4o-transcribe. Groq and custom OpenAI-compatible servers can be selected in settings.
- Download the published APK from the project site or GitHub Releases, or build one locally.
- Open OpenVoiceIME from the launcher.
- Grant microphone permission.
- Choose a provider preset or configure a custom OpenAI-compatible server.
- Enter an API token and model.
- Tap the server test button to verify connectivity.
- Open Android keyboard settings and enable OpenVoiceIME.
- Switch to OpenVoiceIME from the keyboard picker when you want to dictate.
Run commands from the repository root.
.\gradlew.bat testDebugUnitTest assembleReleaseThe release APK is written to:
app/build/outputs/apk/release/OpenVoiceIME-release.apk
Install it on a connected device or emulator with:
adb install -r app/build/outputs/apk/release/OpenVoiceIME-release.apkFor local debug builds, use:
.\gradlew.bat assembleDebugOn macOS/Linux, use:
./gradlew testDebugUnitTest assembleReleasePublic APKs are distributed through GitHub Releases. Each release should include:
OpenVoiceIME-release.apk- A short changelog.
- Any known setup or compatibility notes.
Release builds block cleartext HTTP and disable app backup to protect provider credentials. Debug builds allow cleartext HTTP for local development endpoints.
The project site also hosts the latest signed APK at:
docs/downloads/OpenVoiceIME-release.apk
OpenVoiceIME currently has one OpenAI-compatible transcription client. Providers with different upload flows, authentication schemes, or response formats need separate adapters.
| Service | Status | Base URL | Default model |
|---|---|---|---|
| OpenAI | Supported default | https://api.openai.com |
gpt-4o-transcribe |
| Groq | Supported | https://api.groq.com/openai |
whisper-large-v3-turbo |
| Custom OpenAI-compatible server | Supported as saved custom preset | User-provided | User-provided |
| Deepgram | Needs adapter | Different endpoint/auth/response | N/A |
| AssemblyAI | Needs adapter | Upload + async polling flow | N/A |
| Google Speech-to-Text | Needs adapter | Google recognizer JSON/OAuth flow | N/A |
| Azure Speech | Needs adapter | Azure speech REST path/auth/body | N/A |
Expected compatible request shape:
POST {baseUrl}/v1/audio/transcriptions
Authorization: Bearer <token>
Content-Type: multipart/form-dataMultipart fields:
file: recorded audiomodel: configured transcription modellanguage: optional language codetemperature:0.0
Expected success response:
{
"text": "Transcribed text"
}OpenVoiceIME records audio on device, but transcription happens on the configured remote server. Audio and API credentials are therefore subject to the provider or self-hosted service you configure.
Project rules:
- API tokens are stored locally using encrypted app storage.
- API tokens and transcript text should not be logged.
- Private server URLs, API tokens, and generated APKs should not be committed.
- Custom cleartext HTTP endpoints are possible for local development, but public usage should prefer HTTPS.
app/src/main/java/dev/rankis/openime/
audio/ Local microphone recording
stt/ Transcription provider client and diagnostics
settings/ Settings models, persistence, and screen
metrics/ Local response-time statistics
Resources live in app/src/main/res/. JVM tests live in app/src/test/java/.
Useful first areas:
- Add a provider adapter behind the
SttProviderinterface. - Improve setup diagnostics for Android IME edge cases.
- Add focused tests for parsing, validation, metrics formatting, and provider request mapping.
- Improve release packaging and install documentation.
Before opening a pull request, run:
.\gradlew.bat testDebugUnitTest assembleReleaseUse Conventional Commit subjects such as feat(stt): add provider adapter or fix(ime): handle empty recording.
OpenVoiceIME is licensed under the Apache License, Version 2.0. See LICENSE.