An Android translator app that performs text and image translation completely offline using on-device models.
Supports automatic language detection and transliteration for non-latin scripts. There's also a built-in word dictionary.
Complete offline translation - download language packs once, translate forever without internet.
Language packs contain the full translation models, translation happens on your device, no requests are sent to external servers.
- Translation models are firefox-translations-models
- The translation models run on bergamot-translator
- OCR models are Tesseract
- Automatic language detection is done via cld2
- Dictionary is based on data from Wiktionary, exported by Kaikki
- For Japanese specifically, there's a second "word dictionary" (Mecab) for transliterating Kanji
- TTS uses Piper, Coqui, Kokoro, MMS, Sherpa ONNX, Mimic3 voices
There are two ways to translate content from other apps.
Press a button or use a gesture to translate whatever's on your screen. To enable it, go through the app settings, or on your phone:
Settings > Apps > Default apps > Digital assistant app and select 'Translator'.
Note: voice integration is not supported yet, and Android only allows one assistant at a time.
Places a floating bubble on screen that you can tap to translate the current screen at any time. To enable it:
Settings > Accessibility and enable 'Translator'.
Apps tend to provide better data through accessibility than through the assistant interface, but your mileage may vary.
This app exposes an API (see ITranslationService.aidl) that other apps can use to request translations.
If you want to use this app on a device with no internet access, you can put the language files on Documents/dev.davidv.translator. Check
OFFLINE_SETUP.md for details.
This app works fine on aarch64, and it "works" on x86-64 -- in quotes because it currently requires AVX2, which is not available on the standard emulator, nor in the ABI.
You can be cheeky and run a VM with a good CPU configuration like this
cd $ANDROID_SDK/emulator
export LD_LIBRARY_PATH=$PWD/lib64:$PWD/lib64/qt/lib
$ANDROID_SDK/emulator/qemu/linux-x86_64/qemu-system-x86_64 -netdelay none -netspeed full -avd Medium_Phone_API_35 -qt-hide-window -grpc-use-token -idle-grpc-timeout 300 -qemu -cpu max
# The important bit is
# `-qemu -cpu max`If you don't do this, you will just get a SIGILL when trying to load the library.
bash build.shwill trigger a build in a docker container, matching the CI environment.
- Bump
app/build.gradle.ktsversionName and versionCode - Create a changelog in
fastlane/metadata/android/en-US/changelogsas${versionCode*10+1}.txt(and+2) - Build:
bash build.sh - Sign:
bash sign-apk.sh keystore.jks keystorepass pass alias - Create a tag that is
v${versionName}(eg:v0.1.0) - Create a Github release named
v${versionName}(eg:v0.1.0)- Upload both signed APKs to the release
gh release create v0.2.7 -F fastlane/metadata/android/en-US/changelogs/12.txt signed/translator-arm64-0.2.7.apk signed/translator-armv7-0.2.7.apk
Each ABI gets a unique versionCode: versionCode * 10 + abiOffset (armv7=1, arm64=2, x86=3, x86_64=4).
bash sign-apk.sh keystore.jks keystorepass pass aliaswill sign the APKs built by build.sh and place the signed copies in signed/translator-{arm64,armv7}-${version}.apk
SHA-256 hash of signing certificate: 2B:38:06:E7:45:D8:09:01:8A:51:BE:58:D0:63:5F:FC:74:CC:97:33:43:94:07:AB:1E:D0:42:4A:4D:B3:E1:FB
This project was funded through the NGI Mobifree Fund, a fund established by NLnet.






