change language programmatically in android

Change Language Programmatically in Android

While developing your awesome application, sometimes you are required to add a feature to change the language of your app on the fly. However, Android OS does not directly support this behaviour. And therefore, you need to solve this situation in some other ways.

Android by default uses the locale of the device to select the appropriate language dependent resources. And most of the time this behaviour is enough for common applications.

However, sometimes there is some business requirements that you need to implement. To do that I will outline the details of changing the language of your application programmatically on the fly.

Here is the appropriate way of changing the locale of the application:

There are some difficulties which you have to overcome to change the language programmatically.

  1. Your application will not remember your language change after it is closed or recreated during the configuration change.
  2. You should update currently visible UI properly according to the selected language.

Solution

“LocaleHelper” is the solution all you need. You just have to initialize locale on your application’s main class. After that all your language changes will persist.

After the recent changes in Android API Version 24(Nougat) we need to override attachBaseContext to reflect changes.

LocaleHelper.javA

if you call onAttach(Context context) constructor it will just set default locale of your device as the default locale of your application.

if you call onAttach(Context context, String defaultLanguage) constructor it will set the given language as the default language of your application for the first time that your application opens. After that you can change your locale by using the buttons or any other method that you provide to your users through your layout.

MainApplication.java

You need to override attachBaseContext and call LocaleHelper.onAttach() to initialize the locale settings in your application.

MAINACTIVITY.java

Here you can find an example activity which has two buttons and three textviews on it to change the locale of the textviews on the fly.

In your activity override attachBaseContext and call LocaleHelper.onAttach(). After that you just need to take care of the activity or fragment which includes the language change buttons. Other activities will not require any modifications at all.

You have two options to update currently visible layout:

  • First, you can just update the text or any other language dependent resources one by one.
  • Second, you can call activity.recreate() to restart currently loaded activity. Then the activity will reload the resources with the correct locale. However, if you select this option your users will notice the affect because it will close your application and you get black screen for a very small amount of time and then recreate your activity again in meanwhile.

Sample Project

For your reference, I added a sample project on github which can be found here. The sample project is targeting Nougat API 25(7.1). You can easily change the target for your needs.

If you have any question regarding to change locale of your android application, feel free to ask.

  • Best solution

    • Safy

      The current solution does not work for Android Nougat

      • Hello Safy, what is not working exactly for your case? I’m adding a sample project targeting Nougat API 25 (7.1) for your information.

        • Andraž Pajtler

          He probably means that context.getResources().updateConfiguration() has been deprecated in Android API 25.

          • @andrapajtler:disqus Thank you for pointing out. I updated the code and sample project to reflect recent changes in Android API.

  • Er B S Choudhary

    thanks for giving post …..it’s only change the textview something …I wan to change keyboard input language …….

    • It is not possible to do that because the virtual keyboard itself is another system application. You can redirect your user to the settings page to let him/her to change the keyboard language by themselves.

  • Kunal Parte

    i m not able to change my application into Hindi and Urdu.
    Please help me with it –Kunal

    • Hello Kunal,

      Please check that your device is supported Hindu language by going “Settings -> Language & Input”.
      If it is not the problem then you need to create a folder called “values-hi” in your “res” folder.

      Then you have to add strings.xml into values-hi folder.

      And then you can apply the codes that i shared here without any problem.

  • Dmitry Suzdalev

    Note that using “Configuration configuration = resources.getConfiguration(); configuration.locale = locale” is wrong, because according to documentation “the returned Configuration object should be treated as read-only”. So you should do “Configuration configuration = new Configuration(resources.getConfiguration());”, i.e. copy it instead.

  • Hello Günhan, I am using your code to change the language setting in my app but somehow the NavigationView does not get rewritten. Do you have any idea why?
    Thanks 🙂

    • I see your problem, it is because you couldn’t update the navigation view itself.

      As i mentioned you can force the activity to recreate itself by using the correct locale however it has a very poor user experience and maybe thats why you didn’t implement that way.

      What you have to do is, you need to find the menu items in your navigationview manually by using the ids that you provided in your menu.xml
      And then you have to reassign textview texts.

      Also another option is, remove the navigationview from the drawer, and then create a new one assign it to the drawer again.

      Or another option is, it is a little bit tricky solution but, just dont use navigationview’s menu, just set your custom headerview, and in that view you manually manage your list of items. And to do that you have to create a recyclerview in which you can easily update the list of items or any other view very easily.

      Thus, i mentioned also in the post the problem is you have to manually update the current view because activity cannot update itself.

      • Thank you, Günhan. We just dropped this feature and let the system decide the best fit for the language 🙂

        • Sumeet

          I also got the same issue.
          As I was changing language from some other activity.
          So on the onResume() method I wrote this code :

          homeActivityBinding.navView.getMenu().clear();
          homeActivityBinding.navView.inflateMenu(R.menu.activity_home_drawer);

          And it worked out.
          I just cleared and inflated menu again.

          Its working really nice.

  • Luthfi

    Hi, I used you LocaleHelper and it works only when we manually update each views’ text after changing language. But it doesn’t work when I used activity.recreate. Locale.getDefault is still correct though, but the string that was received from getResource is wrong.

    Any help?
    Thanks

    • I’ll recreate your situation and check the problem.

    • I tried like this in my activity.

      private void updateViews() {
      recreate();
      }

      and it works. It correctly changes the locale and updates every view on that activity.

      Maybe you somehow disabled/override the “configuration change” on your AndroidManifest or in your activity’s onCreate method.

    • Gonzalo

      A bit late maybe, don’t forget to update your Manifest and add the android:name to application tag, with the same name of the class you created.

  • Sami Özakyol

    Dil seçimini ayarlar activity de yapıyorum bir çok activity bulunuyor uygulamamda kullandığım kodda iç içe activity leri yenilemekle uğraşmamak için, dil değişikliğinden sonra uygulamayı yeniden başlatıyorum. Uygulama kill olmadığı için yeniden başladığında mainapplication kısmı tekrardan çalışmıyor ve dil değişikliği gerçekleşmiyor. Uygulamayı kill ettiğimde bir sonraki açılışta problem kalmıyor. Sorunun çözümü olarak yeniden başlatmadan evvel system.exit(0) komutunu kullandığımda uygulama sonlandığı için sorun oluşmuyor. Sizin tavsiye edebileceğiniz çözüm nedir? teşekkürler.

    • Merhaba Sami,

      Backstack’de bulunan activity’ler resourcelarını önceden yüklediği için bu sorunla karşılaşmanız normal.

      İlk ve en temiz önerim eğer yapabiliyorsanız dil değişim özelliğini uygulamanızın açılış activity’si üzerinde yapmanız. Böylece bir sonra açılacak activity hali hazırda bu değişimden yararlanacaktır.

      İkinci önerim ayarlar activity’niz kapatılırken setResul() ile dil değişliği yapıldığını simgeleyecek bir resultCode set edebilirsiniz. Ve akabinde backstack2den gelecek activitylerin onActivityResult() methodu içerisinde gelen resultCode’u değerlendirip eğer dil değişimi yapmanız gerekiyorsa yine activity.recreate() yapabilirsiniz veya updateViews ile ekran üzerinde çok view bulunmuyorsa bu işlemi manuel gerçekleştirebilirsiniz.

      Uygulama çalışıyorken dil değişikliği yapılması aslında önerilen bir özellik değil ve bir çok uygulamada bu özellik bulunmuyor. Bu sebeple kullanıcı dili değiştirdiğinde uygulamayı kill etmeniz önermeyeceğim bir çözüm olsa da kullanıcıların anlayışla karşılayacağını düşünüyorum.

  • Gonzalo

    You forget to say that “MainApplication” corresponds to the “android:name” property of the tag in Manifest.

  • Sourabh

    Is this a Java project or Android project? I’m trying to change locale on a real-time device using Java. Any suggestions you can provide?

    • This is for Android projects.

  • Simon Hrovatin

    After i call method LocalHelper.setLocal() in my application the activity title (on top of the screen) doesn’t change. Other content is changed OK. If i completly close the apllication and then open it again the title is set correctly. Can you help me fix this problem so that the title will get changed on the fly?

    • Ankush Chugh

      Call recreate() in current older stacked activities also updated in my case.

  • Ankush Chugh

    When Phone rotates the language shifts back to default one, As we know when phone rotates, onConfigurationChanged is called.

    Hence best thing to do is:

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    LocaleHelper.onAttach(getBaseContext());
    //update locale and resources, configuration on each config change
    }

    Also you don’t need to override this in each activity just do it in Application class and all done.