Android Question Changing Locale of Android

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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 });
 

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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)
 

Attachments

  • More.src.zip
    52.7 KB · Views: 442
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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) {}
}
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can compile this code to a library with SLC:

B4X:
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
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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?
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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
 
Upvote 0

warwound

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

B4X:
	/**
	 * 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:

B4X:
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.
 

Attachments

  • Resources_library_files_20140521.zip
    10.6 KB · Views: 498
Upvote 0

Anuj_Singh

Member
Licensed User
Longtime User
But still not get, how to change Locale programmatically.
Is there any library through which we can set Locale for our device ?
 
Upvote 0

Alberto Iglesias

Well-Known Member
Licensed User
Longtime 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!
 

Attachments

  • VisualNetLib110.zip
    3.6 KB · Views: 428
Upvote 0

Anuj_Singh

Member
Licensed User
Longtime User
In my Samsung Android device and others like Micromax, Motorola & HTC.
Language conversion works fine using xml Resources file & your with your Library
 
Upvote 0

lorebarita

Member
Licensed User
Longtime 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:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…