Suresh's Site

Don't Panic...

  • Home
  • Code
  • Projects
  • Consulting

Changing Android’s Locale Programmatically

March 8, 2016 SJ 7 Comments

Oh, the hacks we do to support user requirements…

In a kiosk app I wrote, I was asked to support setting up a tablet’s wifi and changing the tablet’s language in-app to support a few languages by administrators with lowered permissions (the kiosk app was locked down, the admins in question could not exit the app to go to the settings page).

Like a good, wholesome developer – I followed best practices as well as I could, and I started an intent to load the desired Settings pages:

1
2
3
4
5
6
7
8
9
@OnClick(R.id.button_wifi_setup)
void setupWifi() {
    startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}
 
@OnClick(R.id.button_language_setup)
void setupLanguage() {
    startActivity(new Intent(Settings.ACTION_LOCALE_SETTINGS));
}

When clicked, these buttons will load the Wifi or Language Settings, and when those activities are finished – we come back to the Kiosk app. Worked like a charm, no problems.

Features Are Creeps

The latest feature the client wanted was that ANYONE using the Kiosk app could change the app’s language very quickly (no new screen loaded – e.g. via a drop-down). The other downside of the Locale Settings page was that it shows every language the tablet supports – whether or not those languages are actually translated in the app.

In this case, the client only supported three languages, so showing a list of 30 languages to a user might imply that each of those languages was supported.

At first, I wasn’t sure how possible this feature was – but then I remembered that it was Android, and so everything is possible in some way, shape, or form.

Changing Your Locale

Kudos go out to Gunhan for that post as it’s super helpful.

I’ve re-packaged that work into a non-persisting setup (persistence code is commented out) with a few StringDefs and other cleanup code.

This method does the bulk of the work:

1
2
3
4
5
6
7
8
9
10
11
12
13
private static boolean updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
 
    Resources resources = context.getResources();
 
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
 
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
 
    return true;
}

It selects a new locale from the language string that was passed in, and then updates the app’s resource files.

An example of use (through a static public function) is this:

1
2
3
4
5
6
7
8
@OnClick(R.id.button_change_locale)
void changeLocale() {
    if (++mLanguageIndex >= LocaleUtils.LocaleDef.SUPPORTED_LOCALES.length) {
        mLanguageIndex = 0;
    }
 
    LocaleUtils.setLocale(this, mLanguageIndex);
}

Of note, this new language will ONLY apply to new Activities, not the one you’re currently on.

Instantaneous Locale Update

To get around this little issue, there are a few methods. An easy one is to just re-load the current activity, or have your language changing code in a different activity. That way, when you come back to the original page, the language settings would have taken effect.

I don’t like the user experience in that case.

Another method (untested), is what you would do with a regular settings change, which is to setup a locale change receiver and act upon that. Should work, but feels a bit heavy for me.

My extremely simple, and non-elegant, solution is to have a method on the page where I’m changing languages that just re-loads the strings that are on the page. Usually, there are so few strings that this solution takes seconds to implement.

1
2
3
4
private void setupUi() {
    mChangeLocaleButton.setText(R.string.current_language);
    mLoadActivityButton.setText(R.string.open);
}

Check Out the Code

I’ve created a Github repo here: https://github.com/sureshjoshi/android-locale-example where you can check out the code to see exactly what the LocaleUtils helper looks like.

Feature Photo credit: Rob Lee / Foter / CC BY-ND

Related

Mobile Android, Language, Locale, Mobile

Comments

  1. santosh says

    June 14, 2016 at 1:43 am

    not supported to some devices

    Reply
    • SJ says

      June 14, 2016 at 8:37 am

      Can you be a bit more specific? I was testing this mostly with Kiosks, so it seems to have worked on the Nexus family, Samsung tablets, and a couple of no-names, all Lollipop or above.

      Reply
  2. Dennis says

    September 12, 2016 at 3:24 am

    Configuration’s locale properties was deprecated in API level 24. My similar code don’t work on Android 7.0 emulator. In my app, getResources().getString(..) return resources from default language.
    Any idea on how to modify the related code?

    https://developer.android.com/reference/android/content/res/Configuration.html#locale

    Reply
    • kanxoramesh says

      May 28, 2018 at 3:38 am

      did you find same example of this issue ? please leave a reply

      Reply
      • Rodrigo says

        January 21, 2019 at 2:18 pm

        Any idea how to solve this!?

        Reply
  3. Miguel says

    November 18, 2016 at 8:09 am

    Hello, Nice article!!
    But what about keyboard input ? The locale not change in keyboard. Dou you know if there is any solution for that?
    Thanks!!

    Reply
  4. Daniel Chaibi says

    October 5, 2018 at 1:03 am

    I’m wondering about the same thing, the keyboard? We have a kiosk app where we want to dynamically change the keyboard input based on the language selected by the user in-app. Any experiences?

    Reply

Leave a Reply Cancel reply

Top Posts & Pages

  • Invensense IMUs - What to Know
    Invensense IMUs - What to Know
  • Android Kiosk Mode Without Root
    Android Kiosk Mode Without Root
  • SSIS String Variables in Derived Columns
    SSIS String Variables in Derived Columns
  • You Stream, I Stream, We All Stream For Protocol Buffers
    You Stream, I Stream, We All Stream For Protocol Buffers
  • File Logging in Android with Timber
    File Logging in Android with Timber

Follow me on Twitter

My Tweets

Categories

  • CB (3)
  • Development (28)
  • Embedded (16)
  • Mobile (30)
  • Productivity (13)
  • Thoughts (15)

Copyright © 2019 · Daily Dish Pro Theme on Genesis Framework · WordPress · Log in