Android OTA Localization
Update strings.xml without Google Play resubmission.
Traditional Android localization bakes strings.xml into your APK or AAB. Any translation change — even a single typo fix — requires a new build and a Google Play submission. TranslationsHub delivers string updates Over-The-Air so users see corrections the next time they open the app.
Start for freedependencies {
implementation 'com.translationshub:android-sdk:1.0.0'
}
TranslateHub.initialize(
context = this,
config = TranslateHubConfig(apiKey = "YOUR_KEY")
)
// In any Activity/Fragment:
textView.text = "greeting".translate ?: "Hello!"
How it works
Add via Gradle
One dependency in app/build.gradle. Initialize in your Application class — no Manifest changes needed beyond INTERNET permission.
Manage keys in the dashboard
Add languages and strings at translate-io.com. No strings.xml files to commit or merge across branches.
Strings update automatically
The SDK refreshes once every 24 hours in the background. No Google Play submission needed for translation changes.
Complete integration example
Drop-in replacement for getString(R.string.key).
// MyApplication.kt
import android.app.Application
import com.translationshub.sdk.TranslateHub
import com.translationshub.sdk.TranslateHubConfig
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
TranslateHub.initialize(
context = this,
config = TranslateHubConfig(
apiKey = "YOUR_API_KEY", // from translate-io.com
fallbackFile = "translations" // assets/translations.json
)
)
}
}
// In any Activity or Fragment:
textView.text = "welcome".translate ?: "Welcome!"
btnContinue.text = "continue".translate ?: "Continue"
// Switch language at runtime:
TranslateHub.pickLanguage("he")
activity.recreate()
// RTL support:
val isRtl = TranslateHub.currentLanguage?.direction == "rtl"
val dir = if (isRtl) View.LAYOUT_DIRECTION_RTL else View.LAYOUT_DIRECTION_LTR
window.decorView.layoutDirection = dir
<uses-permission android:name="android.permission.INTERNET" /> to AndroidManifest.xml and place translations.json in the assets/ folder as the offline fallback.
Frequently asked questions
What replaces getString(R.string.key)?
The .translate extension on String in Kotlin. It looks up the key in the cached JSON for the current language and returns null when the key is missing, so you provide a fallback: "key".translate ?: "Default text". In Java, use TranslateHub.get("key") with the same nullable contract.
Does it work with XML layout android:text attributes?
Not directly — XML attribute values are resolved at inflate time, before OTA strings are fetched. Set text programmatically in onCreate or onResume using the .translate extension. For DataBinding, expose a LiveData<String> from your ViewModel that updates after TranslateHub initialises.
What if the user is offline on first launch?
The SDK falls back to the bundled translations.json in your assets/ folder. Once the user goes online the cache refreshes automatically within 24 hours.
Does it support RTL languages like Arabic and Hebrew?
Yes. Each language in the JSON includes a direction field. Check TranslateHub.currentLanguage?.direction == "rtl" and set window.decorView.layoutDirection = View.LAYOUT_DIRECTION_RTL or use android:supportsRtl="true" with activity.recreate() after a language switch.
Is the API key safe to include in the Android binary?
The key identifies your project but cannot access your translations bucket directly. A Cloud Function validates it and issues a short-lived signed URL for each sync. For additional hardening, store the key in local.properties and inject it via BuildConfig so it stays out of source control.
Stop waiting for Google Play review to fix a typo.
Start with a free account — no credit card required.
Create free account