Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

java - Changing locale programmatically not working in some devices

I've the following piece of code:

/**
 * Sets a new Locale for the APP.
 * @param newLocale - Valid new locale.
 */
private static void setLocale( String newLocale )
{
    Locale locale = new Locale( newLocale );
    Locale.setDefault( locale );

    Configuration config = new Configuration();
    config.locale = locale;

    context.getResources().updateConfiguration( config, context.getResources().getDisplayMetrics() );
}

Simple.

However when I run it in a Smartphone (4.1.1), it does work flawlessly. The device changes Strings in order to match the language.

But with a tablet (4.3), it doesn't work. If I output something like:

Log.d("TAG",Locale.getDefault());

The Locale seems to be changed on both devices, but as I said, Strings doesn't get translated to the correct language.

I've done a lot of debugging, and I've spotted a difference between objects: Check out the Configuration object on 4.1.1:

enter image description here

And check out the Configuration Object on the tablet (4.3) enter image description here

As you can see, the only notable difference is the userSetLocale which is set to False on tablet.

So I checked Google SourceCode (https://github.com/android/platform_frameworks_base/blob/master/core/java/android/content/res/Configuration.java), and it states:

 /**
 * Locale should persist on setting.  This is hidden because it is really
 * questionable whether this is the right way to expose the functionality.
 * @hide
 */
public boolean userSetLocale;

Looks like this is affecting me. So as I can't access this value, nor by getter / setter nor by public access, I used reflection in order to change it.

However, after changing it by reflection, even though I've seen that it internally changed (boolean is set to false after reflection), same issue is still up.

Do you guys have any tips?

Meanwhile I will keep testing.

Thanks. TESTING:

  • Nexus 10 - 4.4.2 - OK
  • Nexus 5 - 4.4.2 - OK
  • Tablet 320 dpi - 4.4.2 - OK
  • SmartPhone 480 dpi - 4.3 - OK
  • SmartPhone 160 dpi - 4.1.1 - OK
  • Tablet 160 dpi - 4.3 - NOT OK
  • SmartPhone 320 dpi - 4.1.1 - OK
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is the code I am using for localisation. It is used by + 1m people and never heard of any complaint about not changing strings so I hope it will work for you as well:

On top of class:

Locale myLocale;

Function:

    public void setLocale(String lang) { 
        myLocale = new Locale(lang); 
        Resources res = getResources(); 
        DisplayMetrics dm = res.getDisplayMetrics(); 
        Configuration conf = res.getConfiguration(); 
        conf.locale = myLocale; 
        res.updateConfiguration(conf, dm);
        reloadUI(); // you may not need this, in my activity ui must be refreshed immediately so it has a function like this.
    }

Function Call:

//example for setting English
setLocale("en_gb");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...