Fixing App Localization in Android App Bundles
Having users from different regions and languages and supporting their languages is crucial for the success of mobile applications in today’s world. However, when using app bundles, an optimization process can cause runtime app localization to break. In this article, we will explore the problem in detail and provide a solution.
Understanding the Problem
App bundles are the publishing format for Google Play, it contains the compiled code, resources, and assets of an application. When a user downloads apk from Google Play, the store delivers the optimized apk for that particular device according to the configuration of that device.
However, there is an issue with runtime app localization and app bundles. When using app bundles, the optimized apk does not include unnecessary resources and assets that are not needed for the user’s specific device, resulting in a smaller download size. The problem arises when runtime app localization relies on dynamically loading localized resources or assets that are not included in the optimized APK. Since these resources are not present in the APK, the app may not be able to retrieve and display the appropriate localized content at runtime, leading to errors or missing translations.
Solution -1
One possible solution to this problem is to specify in the build.gradle
file that all resources should be included in the app bundle
android {
// ...
bundle {
language {
enableSplit = false
}
}
// ...
}
This Specifies that the app bundle should not support configuration APKs for language resources. These resources are instead packaged with each base and dynamic feature APK. This ensures that all required localized resources are present in the optimized APK file generated by the app bundle.
This Solution will result in an increase in the size of the bundle. To fix this we have another optimized solution which is downloading resources on demand using PlayCore API
Solution -2
In this solution, we are using SplitInstallManager
class. Whenever the user changes the language, we need to check whether the selected language is installed or not and on basis of it we will set language of the app.
private fun changeLanguage(selectedLangs: String) {
val splitInstallManager = SplitInstallManagerFactory.create(context)
val langs: Set<String> = splitInstallManager.installedLanguages
if (langs.contains(selectedLangs)) {
//TODO: Change Language Here
} else {
val installRequestBuilder = SplitInstallRequest.newBuilder()
installRequestBuilder.addLanguage(Locale.forLanguageTag(languageSelected))
splitInstallManager.startInstall(installRequestBuilder.build())
splitInstallManager.registerListener(object : SplitInstallStateUpdatedListener() {
fun onStateUpdate(splitInstallSessionState: SplitInstallSessionState) {
if (splitInstallSessionState.status() === SplitInstallSessionStatus.INSTALLED) {
//TODO: Change Language Here
}
}
})
}
}
Next, when a user opens the app we have to install the downloaded languages. which is done in the attchBaseContext()
method.
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// It will install all the downloaded langauges into the app
SplitCompat.install(this);
}
Done!
For more information, you can check the official documentation