1. *** New version of B4J is available ***
    B4J v7.8
    Dismiss Notice

Android Question Changing Locale of Android

Discussion in 'Android Questions' started by Alberto Iglesias, May 21, 2014.

  1. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    Anyone know how change the Android Locale?

    Is possible with CORE of B4A or need create a library with this routine?

    Class localClass = Class.forName("android.app.ActivityManagerNative");
    Object localObject = localClass.getMethod("getDefault", null).invoke(localClass, null);
    Configuration localConfiguration = (Configuration)localObject.getClass().getMethod("getConfiguration", null).invoke(localObject, null);
    localConfiguration.locale = paramLocale;
    setUserSetLocale(localConfiguration, true);
    localObject.getClass().getMethod("updateConfiguration", new Class[] { Configuration.class }).invoke(localObject, new Object[] { localConfiguration });
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    I'm pretty sure that it is not possible to programmatically change the device locale. You can use Reflection library to implement this code or create a small library.
     
  3. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    I´m installed the app MORELOCATE and it´s do this, works for me in google glass

    https://www.c-lis.co.jp/our_services/morelocale-2

    but I can now put inside my code to not depend this app.

    You can choose country and language and then update configuration... done! Works!

    Look the code of app (attachement)
     

    Attached Files:

  4. Erel

    Erel Administrator Staff Member Licensed User

    You will need to create a small library from this code. It shouldn't be difficult.
     
  5. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    I´m trying,trying,trying...... :-(
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Where is setUserSetLocale method?
     
  7. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    is in MoreLocale.java in source code

    but is this:

    private static void setUserSetLocale(Configuration paramConfiguration, boolean paramBoolean)
    {
    Class localClass = paramConfiguration.getClass();
    try
    {
    localClass.getField("userSetLocale").set(paramConfiguration, new Boolean(paramBoolean));
    return;
    }
    catch (IllegalAccessException localIllegalAccessException) {}catch (NoSuchFieldException localNoSuchFieldException) {}
    }
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    You can compile this code to a library with SLC:

    Code:
    package aaa.bbb;

    import java.util.Locale;

    import android.content.res.Configuration;
    import anywheresoftware.b4a.BA.ShortName;

    @ShortName(
    "ChangeLocale")
    public class test {
       
       
    public void ChangeLocale(String language, String country) throws Exception {
         Class localClass = Class.forName(
    "android.app.ActivityManagerNative");
         Object localObject = localClass.getMethod(
    "getDefault"null).invoke(localClass, null);
         Configuration localConfiguration = (Configuration)localObject.getClass().getMethod(
    "getConfiguration"null).invoke(localObject, null);
         localConfiguration.locale = new Locale(language, country);
         setUserSetLocale(localConfiguration, 
    true);
         localObject.getClass().getMethod(
    "updateConfiguration", new Class[] { Configuration.class }).invoke(localObject, new Object[] { localConfiguration });
       }

       private static void setUserSetLocale(Configuration paramConfiguration, boolean paramBoolean)
       {
         Class localClass = paramConfiguration.getClass();
         try
         {
           localClass.getField("userSetLocale").set(paramConfiguration, new Boolean(paramBoolean));
           return;
         }
         catch (IllegalAccessException localIllegalAccessException) {}catch (NoSuchFieldException localNoSuchFieldException) {}
       }
    }
    Locale documentation: http://docs.oracle.com/javase/7/docs/api/java/util/Locale.html
     
  9. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    uhuuuuuuuuuuuu!!!!!! I´m try right NOWWWWWWWWWWW i tell you later
     
  10. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    Erel,

    Is working but only save configuration after I exitapplication, look

    Dim objVisualNet As VisualNet
    objVisualNet.Initialize("VisualNet")
    objVisualNet.ChangeLocale("fr","FR")
    Log("CheckPermission = " & objVisualNet.CheckPermission("android.permission.CHANGE_CONFIGURATION"))
    LogColor("Locale_country = " & objVisualNet.Locale_country,Colors.Red)
    LogColor("Locale_language = " & objVisualNet.Locale_language,Colors.Red)


    After 1o run (Not changed)
    ** Activity (main) Create, isFirst = true **
    CheckPermission = true
    Locale_country = US
    Locale_language = en

    After 2o run (changed)
    ** Activity (main) Create, isFirst = true **
    CheckPermission = true
    Locale_country = FR
    Locale_language = fr


    Do you know why? Some update when you exit of application?
     
  11. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    Erel,

    I found.. look below, I put exactly the same line before setUserSetLocale to save first and then apply to user configuration and works!


    public void ChangeLocale(String language, String country) throws Exception
    {
    Class localClass = Class.forName("android.app.ActivityManagerNative");
    Object localObject = localClass.getMethod("getDefault", null).invoke(localClass, null);
    Configuration localConfiguration = (Configuration)localObject.getClass().getMethod("getConfiguration", null).invoke(localObject, null);
    localConfiguration.locale = new Locale(language, country);
    localObject.getClass().getMethod("updateConfiguration", new Class[] { Configuration.class }).invoke(localObject, new Object[] { localConfiguration });
    setUserSetLocale(localConfiguration, true);
    localObject.getClass().getMethod("updateConfiguration", new Class[] { Configuration.class }).invoke(localObject, new Object[] { localConfiguration }); }


    I do this based in this code: Look the sub changeTheme in this code
    https://code.google.com/p/my-projec...c/com/cybercom/rcs/skin/SkinFactory.java?r=21

    THANKSSSSSSSSSSSSSSSS
     
  12. warwound

    warwound Expert Licensed User

    I've had to do this at the start of the week.
    Did some research and created this library method:

    Code:
    /**
         * Set the default Locale used 
    to get resources.
         */
        
    public static void SetDefaultLocale(java.util.Locale Locale1){
            android.content.res.Resources currentResources = BA.applicationContext.getResources();
            AssetManager assetManager = currentResources.getAssets();
            DisplayMetrics displayMetrics = currentResources.getDisplayMetrics();
            Configuration configuration = new Configuration(currentResources.getConfiguration());
            configuration.locale = Locale1;
            new android.content.res.Resources(assetManager, displayMetrics, configuration);
        
    }
    Calling the Resources class constructor results in the global instance of the AssetManager to be re-constructed and it'll be re-constructed using the Locale of the Configuration passed to it's constructor.
    This is not officially documented but is widely reported on forums to be true...
    Methods that return a localized value will now return a localized value based on that passed Locale - and this means call to Resources will return localized strings.

    Now in my b4a code i can do:

    Code:
    Dim ApplicationResources As Resources
    ApplicationResources.Initialize(ApplicationResources.RESOURCE_SOURCE_APPLICATION)
    Dim DeviceLocale As Locale
    DeviceLocale=DeviceLocale.GetDefault

    Log("Device Locale: "&DeviceLocale.GetLanguage)

    Dim SupportedLocales() As Locale=Array As Locale(DeviceLocale.CHINESE, DeviceLocale.ENGLISH, DeviceLocale.JAPANESE, DeviceLocale.KOREAN)
    For Each SupportedLocale As Locale In SupportedLocales
        ApplicationResources.SetDefaultLocale(SupportedLocale)
        ApplicationResources.Initialize(ApplicationResources.RESOURCE_SOURCE_APPLICATION)
        
    Log("Processing values for Locale: "&SupportedLocale.GetLanguage)
        
    '    here i fetch application resources such as strings
        '    and have created xml string resources for 4 different languages
        '    so i'm iterating through each Locale that i have defined
    Next

    '    restore the device's original Locale
    '    if you don't do this then the application will continue with the previous Locale passed to ApplicationResources.SetDefaultLocale
    ApplicationResources.SetDefaultLocale(DeviceLocale)
    ApplicationResources.Initialize(ApplicationResources.RESOURCE_SOURCE_APPLICATION)
    Alternatively, the java Locale class does have a (simple) static method setDefault(Locale locale).
    Here's the official documentation:

    The android R class has no getter methods that allow you to pass a Locale instance, my working code was the only solution i found.

    Library files attached if you want to try them.

    Martin.
     

    Attached Files:

    DonManfred likes this.
  13. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    Thanks warwound,

    I will try to use this and compare this two codes, my new library with change locate is ok now, but is in beta test.

    I will try in Google Glass to test and then I tell you if works.

    Tks
     
  14. Anuj_Singh

    Anuj_Singh Member Licensed User

    But still not get, how to change Locale programmatically.
    Is there any library through which we can set Locale for our device ?
     
  15. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    Hey Anuj_Singh,

    I create a little library to to this for me, and I put this simple lines in my Actvity_Create to change locale when I need.


    Look this example: To change the locate to PORTUGUESE/BRAZIL, I put this lines and thats it!

    Dim objVisualNet As VisualNet
    objVisualNet.Initialize("VisualNet")
    objVisualNet.ChangeLocale("pt","BR")



    Hugs!
     

    Attached Files:

    Multiverse app and Ohanian like this.
  16. Anuj_Singh

    Anuj_Singh Member Licensed User

    Thank you Very much Alberto..!
    This is the library what I want to Search for.

    Thanks!
    Regards,
    Anuj
     
  17. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    At my Google Glass I had to Root it, but not on another device, why had not yet available.

    test with your device to see if it works nicely.
     
  18. Anuj_Singh

    Anuj_Singh Member Licensed User

    In my Samsung Android device and others like Micromax, Motorola & HTC.
    Language conversion works fine using xml Resources file & your with your Library
     
  19. Alberto Iglesias

    Alberto Iglesias Well-Known Member Licensed User

    ok. perfect! Enjoy!
     
  20. lorebarita

    lorebarita Member Licensed User

    Hi I like this library to change the language dynamically. It works well in my Samsung Android device but it does not work in a Chinise phone(Rugged phone). My app is meant for this type of phone. Any help will be appreciated.

    This is the error I get even after adding AddPermission(android.permission.CHANGE_CONFIGURATION)


    java.lang.reflect.InvocationTargetException


    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.visualnet.lib.visualnet.ChangeLocale(visualnet.java:196)
    at com.etc.utils.nfc.main._img_france_click(main.java:879)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:162)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:158)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
    at android.view.View.performClick(View.java:4212)
    at android.view.View$PerformClick.run(View.java:17476)
    at android.os.Handler.handleCallback(Handler.java:800)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5371)


    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.SecurityException: Permission Denial: updateConfiguration() from pid=20946, uid=10088 requires android.permission.CHANGE_CONFIGURATION
    at android.os.Parcel.readException(Parcel.java:1425)
    at android.os.Parcel.readException(Parcel.java:1379)
    at android.app.ActivityManagerProxy.updateConfiguration(ActivityManagerNative.java:2965)
    ... 21 more
    java.lang.reflect.InvocationTargetException
     
    Last edited: Sep 10, 2014
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice