Android changing app language

Conversion By Translation: Changing Your Android App Language At Runtime

You have an awesome app with lots of cool features, one of which is multi-language support for your users. Everything works great but your Product Manager wants to improve conversion by prompting users to choose the app’s language on the first launch as part of the onboarding process.
With a couple of years of Android experience under your belt, you’re thinking,
“How hard can it be?”

The Problem

On Android, there is no official support, documentation or API to change an entire app’s language at runtime. When a user opens an app, the resource framework automatically selects the resources that best match the device language settings. In Google Maps, for example, you can not change the street names on the map without changing the entire device language.

Prerequisite

In order to change an app’s language (or Locale in Android terms), we need to be familiar with 2 different mechanisms that will help us achieve our goal:

Configuration Class

This class describes all device configuration information that can impact the resources the application retrieves. This includes user-specified configuration options (locale list and scaling)

Basically, this is the class that Android is gettings its Locale information from.
Overriding this class with the Locale that represents the user’s selected language will change the folder Android is looking for its resources (e.g strings.xml).

Locale.setDefault() Method

Gets the current value of the default locale for this instance of the Java Virtual Machine.

The Default Locale is usually used when using operations like formatting text, parsing numbers or handling dates. So it is important to override it, otherwise, an app may be displayed in the correct language but things like dates and currency will be broken.

The Solution

From API 17 and above, the preferred way to override a Configuration is by wrapping the currently used Context in a new Context using the method below:

We can combine all the actions we need to take into a single function:

This method should be called inside the attachBaseContext() method in the Application class and in each Activity.

As far as the Android system implementation goes, we are done!
(or so I thought? more on that later)

A few things you should do in order to achieve this:

  • The selected language should be persisted in Room/SharedPreferences/etc in order to retrieve it later ( CreateLocaleFromSavedLanguage() method in the snippet above)
  • Reflect the language change by re-creating your Activity or Fragment (this will result in calling attachBaseContext() and modifying the current Context )
  • Optional: Load fresh data from the server based on the selected language, like translated strings or specific business logic directed to the selected language users

A Game of Cat & माउस्

The feature is done and you confidently mark it as ready for QA testing. 💪
As the days pass, bug tickets pile up, each with a different scenario that made the app look like it is partially translated to the selected language and partially using the device language.

Below are 2 example scenarios, there are probably more weird cases, so keep that in mind if you decide to go on this road.

#1: System Language Change

If the user changes the device’s main language while your app is in the background, your app Locale will be overridden by the Android system to reflect the new system language.

Читайте также:  Philips myremote для android

The fix, in this case, is to override the onConfigurationChanged() method in the Application class and override the Locale using the updateConfiguration() method found in Resource class.

#2: WebView

If your app is using WebView in order to display web pages (yeah I hate it too) then you will notice strange behavior every time a WebView is used.
After each WebView creation, the Application Locale gets overridden with the system Locale which messed up the translations. 🤔

The reason behind this is starting with Android N, the Chrome app will be used to render any/all Webviews in third-party Android apps. Because Chrome is an Android app in itself, running in its own sandboxed process, it will not be bound to the Locale set by your app. Instead, Chrome will revert to the primary device Locale .
Source: https://stackoverflow.com/a/40675539/5516215

The fix, in this case, is again to override the Locale after a WebView is created using the technique we wrote above. One way of doing this is by using a custom WebView :

Hopefully, this issue should be resolved in Android 10, where the Chrome app will no longer be the WebView provider.
Source: https://www.xda-developers.com/google-chrome-no-longer-webview-provider-android-10/

Conclusion

After a few iterations, everything looks good. The Product Manager is happy, your users are happy and even you feel quite pleased with implementing a feature that is not officially supported. 👏
With that said, future Android versions can change how this solution affects your app and even introduce new edge cases that require special care, it is up to you to decide if the investment is worthwhile.

Источник

Android App-Specific Language Change Programmatically Using Kotlin

By default, Android will try to load resources based on the System language that is set on the user’s phone. Therefore, if a Tamil language user, Kavi, with her Android set to the Tamil language opened our android application on her phone, she’d see an app localized to her own language.

But what if another user wants to use the Tamil language for his android application on an Android that has its default language set to English?

To deal with this, we will have to programmatically update the locale of our android application to override the default locale set in the user’s system. Here we gonna do ask the user to choose the language and switch the language in application only.

Let’s start with creating new resource files for the Tamil language using Android Studio’s resource file wizard.

Firstly, right-click on the res folder and choose “New -> Android resource file”: It will show prompt like this type file name as strings.xml

Here select the language,

It will generate XML for you then you can put sample string like below.

English default look like

Newly added Langauge Tamil look like

That’s it we configured strings locale.

Now let’s create a ContextUtils utility class to hold our locale updating methods. Place this within a utils package on the android application, as follows:

  1. Configuration.localethe field was deprecated in API level 24 (Nougat). This was put in place by Android API developers to make coders move to the use of getters and setters instead of directly accessing variables.
  2. This was marked as the preferred way of setting up locales (instead of using the direct accessor or setLocale(java.util.Locale)) starting from API level 24.
  3. Before API level 24, developers could directly access the configuration.locale field to change it as they pleased.
Читайте также:  Не обнаруживает сеть андроид

Then we can use this method to apply locale changes.

Create BaseActivity which is extends AppCompatActivity and it must be inherited by other activities.

We going to use attachBaseContext override method to update locale configuration to ACTIVITY so it will reflect on all other activities which are extended by.

Q: What is the use of AttachBaseContext?

A: The attachBaseContext function of the ContextWrapper class is making sure the context is attached only once. ContextThemeWrapper applies theme from application or Activity which is defined as android:theme in the AndroidManifest.xml file. Since both Application and Service do not need theme, they inherit it directly from ContextWrapper . During the activity creation, application and service are initiated, a new ContextImpl object is created each time and it implements functions in Context .

LanguageChooseActivity → MainActvity

Here we store inside SharedPreference a string that contains language code like for tamil →“ta” , English →”en”, Hindi →”hi” etc…

This code used to identify the Language using Locale(«language-code»)

After applying in base activity wherever the strings are used automatically translated.

Below is the sample activity that extends BaseActivity().

Just extends BaseActivity is enough and see the magic. 😉 Hope user won’t get lost in application.

Источник

Changing App language in Android

In your app, you can add as many languages as you want. By languages, I mean the language of the text that we see in any mobile application. For example, if you have English, French, and Hindi users, then you can have language support for all these languages. Like «Hello» in English will become «Bonjour» in French and «नमस्ते» in Hindi.

But how can we change the language? That’s the topic for this blog. In this blog, we will learn how to change the App locale in Android with ease.

By default, you have English as your default language for the whole app and the text corresponding to the English language will be there in our strings.xml file. So, similarly, for other languages, you need to add their strings.xml file.

So, basically Android loads the resources related to language based on the system locale setting. For example, if the language of your Android phone is English, then strings.xml of English will be loaded by Android. We do not have to do anything extra here.

But, many times, we want our users to change the language of our App only by selecting the preferred language and not by changing the language of our Android phone. So, let’s see how to add this.

First of all, create a project in Android Studio. Here, we will be having 2 activities:

  • MainActivity: This will contain one welcome TextView and two Buttons, one for opening the next activity in the English language and the other for opening the next activity in the Hindi language.
  • LanguageActivity: This will simply contain a TextView displaying some message. The message will be shown in English if the language of the app is English and the message will be shown in Hindi if the language of the app is Hindi.

So, let’s start with the MainActivity. The following is the code for the activity_main.xml file:

Here, we have 1 TextView and 2 Buttons.

Similarly, you can add one TextView in your LanguageActivity. The following is the XML code for the same:

And finally, here is the strings.xml file:

So, we are done with our prerequisite part. Now, we are ready to add a new language to our app. Follow the below steps to do so:

  • Right Click on res > New > Android Resource File
  • Put the file name as strings.xml
  • Select the option of Locale
Читайте также:  Android studio textview click

  • Select the locale for Hindi with code «hi»

  • Click on Ok and now, you will be having two values directory i.e. the default one with the name values and the other with name values-hi . The default one will contain the strings.xml file for the default language(in our case, English) and the values-hi will contain the strings.xml file for the Hindi language.

Now, you need to put all the values of all the strings that we defined in our default strings.xml file for our new Hindi strings.xml file.

But there are certain cases where we want to keep the text of the default language. For example, the name of the App should be the same for all languages. In our case, we just need to translate the message that is shown on the LanguageActivity and not all texts like AppName, WelcomeMessage, etc.

So, for that, we need to set translatable to false in our default strings.xml file(the English one). For example:

Similarly, you can set translatable = «false» for other string values as well. Now, for the other strings that you want to translate, you can simply add their values in the strings.xml file of the Hindi language. For example, the code of strings.xml (hi) will be:

In this way, you are telling the Android app to use the string value according to the locale of the App.

Now, our final task is to change the locale or simply the language of the app when we click on the button. For this, add the below function in your MainActivity.kt file:

In the above code, pass the context and the language code and then start the LanguageActivity . For example:

Now, when you open the LangaugeActivity, then you can see the changes in the language.

Points to keep in mind:

  • Whenever an activity is loaded then the corresponding string.xml file is loaded at that time only. For example, if the current locale of your app is English and on button click, you changed it to Hindi. Then no change on that particular activity will be observed because the string file of that activity is already loaded. But if you move to some other activity and then come back to the first activity, then you will see the language changes. If you want to see instant changes, then you need to refresh the activity after the change of the locale.
  • In some Android Versions, you might not see the locale change if you are opening some WebView in your app. Always take care of the case when you load the WebView for the very first time. One possible option is to set again the locale after loading the WebView.
  • You need to handle the case of orientation change of your activity. The locale will be reset in this case as well, so handle this as well.
  • It is recommended by Android to not change the locale at runtime. So, you can avoid this if the use-case of language is not that much important in your app.

This is how you can change the locale of your App. That’s it for this blog. Hope you enjoyed this blog.

Источник

Оцените статью