I have implemented change language from settings as per this ans , but after killing of my application some of the screen of application turned to english.
I have implemented code as below
Code for Splash Screen
String deviceLanguage = Locale.getDefault().getLanguage();
if (!"en".equalsIgnoreCase(deviceLanguage) && !"ar".equalsIgnoreCase(deviceLanguage)){
deviceLanguage="en";
}
((AppController)getApplication()).appLang= Utilities.getSaveData(this, getString(R.string.key_language),deviceLanguage);
Code for Detail Activity
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(MyContextWrapper.wrap(newBase, ((AppController)newBase.getApplicationContext()).appLang));
}
Note : I got this problem in one plus 3T device and genymotion emulator with 5.1 android version
final Resources res = appContext.getResources();
final Configuration conf = res.getConfiguration();
conf.locale = new Locale("ar", "AE");
res.updateConfiguration(conf, null);
After updating configuration, Restart the activity as mentioned below
finish();
final Intent intent = getIntent();
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
Related
My Android Application is Multilanguage. When the user changing app Language, the app saves it in SharedPreferences to make changes permanent (set locale when the app opens).
The way I change language:
public static void changeInterfaceLanguage(Activity activity, #Language String lang) {
Resources res = activity.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
Locale currentLocale = getCurrentLocale(activity);
final Locale newLocale = new Locale(lang);
if (!currentLocale.equals(newLocale)) {
SettingsPrefsEdit.putString(activity, SettingCons.INTERFACE_LANGUAGE, lang);
conf.setLocale(newLocale);
res.updateConfiguration(conf, dm);
activity.recreate();
}
The way I restore Locale when the app opens:
#Override protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String lang = SettingsPrefsGet.getString(activity, SettingCons.INTERFACE_LANGUAGE,
SettingCons.LANG_ENGLISH);
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
activity.getResources()
.updateConfiguration(config, activity.getResources().getDisplayMetrics());
...
}
Also, Admob Native Ads is implemented in this App.
The problem is this:
After destroying app and reopen it, exactly when my code calls any method from Admob library, the app language (Locale) is changing to English, and after that, every new screen of the app is in English.
Some of the methods that cause this problem:
MobileAds.initialize(this)
AdLoader.Builder adLoader = ...
adLoader.build().loadAd(new AdRequest.Builder().build());
Useful notes:
SharedPreferences doesn't get change when this problem occurs.
There is only one Activity in the app. All pages are implemented as Fragment (50+ pages)
After changing app language, everything is fine until app getting destroyed
I'm using Firebase version of Admob:
implementation 'com.google.firebase:firebase-ads:19.6.0'
What I've tried:
When I disable all calls to Admob methods, the problem disappears.
I moved locale update code block to MainApplication. But the problem exists yet.
I re-implemented Language change operation with this library, but didn't resolve:
https://github.com/YarikSOffice/lingver
I have a method that translates my application from English to Swedish and back again if the user so wishes. However, I don't really like the fact that the activity restarts every time because it's giving me a hard time with the savedInstaceState and I've had several crashes because of this.
Here's how my method that changes language looks:
public void setApplicationLanguage(String language) {
myLocale = new Locale(language);
Resources res = activity.getResources();
DisplayMetrics display = res.getDisplayMetrics();
Configuration configuration = res.getConfiguration();
configuration.locale = myLocale;
res.updateConfiguration(configuration, display);
Intent refresh = new Intent(activity, StartupActivity.class);
activity.startActivity(refresh);
}
Is there any chance that the same function can be applied without the:
Intent refresh = new Intent(activity, StartupActivity.class);
activity.startActivity(refresh);
?
Try this
I also had this issue.I used the code below and then it changed the language without refreshing the activity
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);
onConfigurationChanged(conf);
/*Intent refresh = new Intent(this, AndroidLocalize.class);
startActivity(refresh);*/
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// refresh your views here
lblLang.setText(R.string.langselection);
super.onConfigurationChanged(newConfig);
// Checks the active language
if (newConfig.locale == Locale.ENGLISH) {
Toast.makeText(this, "English", Toast.LENGTH_SHORT).show();
} else if (newConfig.locale == Locale.FRENCH){
Toast.makeText(this, "French", Toast.LENGTH_SHORT).show();
}
}
declare in Manifest android:configChanges="locale"
You can replace the code:
Intent refresh = new Intent(activity, StartupActivity.class);
activity.startActivity(refresh);
With the method from Activity class:
recreate();
I hope your minimum SDK version will support because it was introduce in SDK 11. Your activity will be recreate as a new instance remember! Everything will be started afresh. From my experience it is fast compared to making a new Intent. But if you want to pass some data the method of using Intent is better than that! You can add extras to the Intent.
Create a singleton class:
public class Singleton {
private static Singleton mInstance = null;
private int repeat = 0;
public int getRepeat() {
return repeat;
}
public void setRepeat(int repeat) {
this.repeat = repeat;
}
}
Now you have a method that you can set and get the data, so make a method and put it under onResume() method, call your method and you can get and set the data like this:
Singleton.getInstance().setRepeat(1);
Singleton.getInstance().getRepeat();
I have a singleTask activity and my app supportsRtl, so when I try to change the language, this SingleTask activity is not affected so I need to restart it, Any help?
If you're using API 11 and above you can use the:
Activity.recreate()
If you need to support lower API use this to call your activity again:
Intent i = getIntent();
finish();
startActivity(i);
If we use this approach we don't need to restart the activity
change your app language with the following code:
public static void notifyForLanguageChange(Context context, String languageCode) {
Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(languageCode.toLowerCase());
res.updateConfiguration(conf, dm);
}
and after that change your screen labels with(i.e reload string resources)
public void setLabels() {
txtFirstView.setText(R.string.first);
txtSecondView.setText(R.string.second);
btnThirdView.setText(R.string.third);
}
I've create an activity to change the locale of the application to load resources of the selected language and I restart the application,moreover I'm keeping an integer value as the app state using sharedpreferences,after setting the locale via the following code,the next time that I open the application the mentioned state does not have the correct value!!!!But,when I remove the language setting there isn't any problem with the state of the application!
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
/*
* Intent refresh = new Intent(this, AndroidLocalizeActivity.class);
* startActivity(refresh); finish();
*/
PrefManager _p = new PrefManager(getApplicationContext(), PrefConfigNames.LANGUAGE_APP_CONFIG);
_p.setStringValue(GeneralPrefKeyNames.LANGUAGE, lang);
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
setResult(RESULT_OK, null);
finish();
I cannot get what happens to sharedpreferences(I've used open source securepreferences (CodeProject article)in this app)
here!!!
Thanks in advance
Edit#1
PrefManager.java
public class PrefManager {
private SecurePreferences _securePreferences = null;
public PrefManager(Context context, String PrefName)
{
_securePreferences = new SecurePreferences(context, PrefName);
}
public void setStringValue(String key, String value)
{
_securePreferences.edit().putString(key, value).commit();
}
}
Edit#2
Something which is so weird is that the state of the application stored in the sharedprefs has the correct value when I debug or run the application from eclipse (debug or run as an android application)!!!but when I rerun it on the phone it has the default value!!!Please help me solve this issue!
Edit#3
I found out that there was a problem with relaunching the application using the following lines,is there another way to relaunch the app without any problem???Or even a better way (to update the language without relaunching the app)?
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
I've tried the following link to achieve the second mentioned approach
Changing locale: Force activity to reload resources?
,but it is not being raised after the following line
res.updateConfiguration(conf, dm);
Thanks in advance
I finally got the solution,in the onPause method I save the currently saved language in the sharedprefs and after changing the locale in the setting activity and returning to the previous activity in the onResume method I compare the newly saved lang with the value kept in the onPause,and if these two are not equal I call recreate method.
#Override
protected void onResume()
{
super.onResume();
SharedPreferences _sPreferences = getSharedPreferences(PrefConfigNames.LANGUAGE_APP_CONFIG,
Context.MODE_PRIVATE);
String resumeLang = _sPreferences.getString(GeneralPrefKeyNames.LANGUAGE, "En");
if (!currentLang.equals(resumeLang))
recreate();
};
#Override
protected void onPause()
{
SharedPreferences _sPreferences = getSharedPreferences(PrefConfigNames.LANGUAGE_APP_CONFIG,
Context.MODE_PRIVATE);
currentLang = _sPreferences.getString(GeneralPrefKeyNames.LANGUAGE, "En");
super.onPause();
};
You should commit() the values
I am trying to change the language of my Android app with no success.
I have:
/res/
. values/
. . string.xml
. . values-es/
. . . strings.xml
Both strings files contains the same but the content is translated according to the language code.
The default language is english but I want to do some tests and use the spanish language.
I use the code written in this previous question:
Change app language programmatically in Android
Here is my LoginActivity(launcher)'s onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setting default screen to login.xml
setContentView(R.layout.login);
Resources res = getBaseContext().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("es");
res.updateConfiguration(conf, dm);
TextView registerScreen = (TextView) findViewById(R.id.link_to_register);
// Listening to register new account link
registerScreen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Switching to Register screen
Intent i = new Intent(getApplicationContext(), RegisterActivity.class);
startActivity(i);
}
});
Button mainMenu = (Button) findViewById(R.id.btnLogin);
// Listening to register new account link
mainMenu.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Switching to Register screen
Intent i = new Intent(getApplicationContext(), MainMenuActivity.class);
startActivity(i);
}
});
}
My target is Android 4.4.
However, this is not working on my Nexus 4 - Android 4.4, it always uses English language.
The values-es folder should be on the same level as the values folder. Your example above looks like you have values-es inside the values folder.