My app language is turkish and device language is english. I can set the language turkish with code below smoothly. All application pages change properly.
private void changeLang(String locale) {
Resources res = this.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(locale.toLowerCase()));
res.updateConfiguration(conf, dm);
Configuration newConfig = new Configuration();
newConfig.locale = new Locale(locale.toLowerCase());
onConfigurationChanged(newConfig);
}
But when Im sending a push notification, Notification text still english. I see the locale still english when Im debug.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Locale current = getResources().getConfiguration().locale;
//current not change, always english
}
}
Why the service cannot get true locale, always get device locale.
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 am trying to change app localization at runtime it working correctly but when clear app from memory and reopen it again I find that resources like strings.xml and styles.xml take the default mobile language!
See my method to localize the app:
I created an abstract class like below:
public abstract class BaseLocalization extends AppCompatActivity {
SharedPreferences preferences;
Constants constants;
String currentLocale = "en";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
constants = new Constants();
preferences = getSharedPreferences(constants.getPreferences(), MODE_PRIVATE);
currentLocale = preferences.getString(constants.getLocale(), "en");
setLocale(currentLocale);
}
public void setLocale(String lang) {
Locale myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
}
}
After doing this, I made all the classes which extended AppCompatActivity extend this class. And saved the locale in SharedPreferences. And the locale is persisted until the app data is cleared/uninstalled.
This question already has answers here:
Change app language programmatically in Android
(34 answers)
Closed 2 years ago.
My aim is to change an application language from English to Chinese during runtime, is there any suggestions?
language_spinner = (Spinner)findViewById(R.id.settings_language_spinner);
language_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (pos == 1){
Toast.makeText(parent.getContext(),"You have selected English",Toast.LENGTH_SHORT).show();
setLocale("en");
}else if (pos == 2){
Toast.makeText(parent.getContext(),"You have selected Chinese",Toast.LENGTH_SHORT).show();
setLocale("zh");
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
}
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
if (!conf.locale.getLanguage().equals(lang)) {
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(this, SettingsActivity.class);
startActivity(refresh);
finish();
}
}
This code is working properly with English but not working with Chinese
please help me in finding the solution ..
I can give you idea how you can implement this:
step 1: make string file for all texts in values directory as string-ch, ch is the code for Chinese language. and in code get every string with the getResources.getString(R.string.text_name); so that it can take string value at run time either English or Chinese.
step 2: now create method :
void changeLanguage(String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
step 3: call this method where you want to change language suppose if you want to get changed language of you application according to device language then you can call as:
changeLanguage(Locale.getDefault().getLanguage());
Create below function in Util like class
public static void setLocale(Activity activity, String languageCode) {
Locale locale = new Locale(languageCode);
Locale.setDefault(locale);
Resources resources = activity.getResources();
Configuration config = resources.getConfiguration();
config.setLocale(locale);
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
Call this function from activity at the start. The original post with this code snippet can be found at Change app language programmatically in Android page.
I have created 4 languages for the app. I can change the Lauaguage, ok, but if close the app and then start I it again, the app starts atfirst with the default string.xml.
How to let the app starts with the last selected Language ?
should I call the the methode by OnCreate in the mainActivity ?
#SuppressWarnings("deprecation")
public void setLocale(String lang) {
Locale myLocale = new Locale(lang);
DisplayMetrics dm = getResources().getDisplayMetrics();
Configuration conf = getResources().getConfiguration();
conf.locale = myLocale;
getResources().updateConfiguration(conf, dm);
Intent refresh = new Intent(this, Languages.class);
startActivity(refresh);
/* "en" = English
"hi" =Hindi
"fr" =French
"it" =Italian
"de" =German
"es" =Spanish
"ja" =Japanese
"ko" =Korean
"nl" =Dutch
"pt" =Portuguese
"ru" =Russian
"zh" =Chinese
"ar" = arabic
*/
}
How can the user change the default language ?
Why don't you store the selected language in shared preferences? That way you can always check for the selected language when your app starts, and then load the appropriate language file.
I have used a long Way like below but it works. Thanks :
OnResume :
selected_lang= myshared.getString("selected_lang","de");
lang_found= Integer.parseInt(myshared.getString("lang_found","0"));
setLocale(selected_lang);
#SuppressWarnings("deprecation")
public void setLocale(String lang) {
Locale myLocale = new Locale(lang);
DisplayMetrics dm = getResources().getDisplayMetrics();
Configuration conf = getResources().getConfiguration();
conf.locale = myLocale;
getResources().updateConfiguration(conf, dm);
if(lang_found==0) {
Intent refresh = new Intent(this, MainActivity.class);
startActivity(refresh);
lang_found=1;
}
#Override
protected void onDestroy() {
lang_found=0;
Save_setting();
super.onDestroy();
}
So I have a language setting in my application. When the language is switched, I would like all the textviews etc to change language immediately. Currently I just change the locale in the configuration, so the language has changed when the user restarts the activity.
An ugly solution to my problem would be to make each textview load the new resources each time the language is changed. Is there a better solution? Perhaps a neat way to discretely restart the activity? Or maybe just force reload of the resources?
In your AndroidManifest.xml, add this attribute to your Activity
android:configChanges="locale"
In your activity override onConfigurationChanged()
#Override
public void onConfigurationChanged(Configuration newConfig) {
// refresh your views here
super.onConfigurationChanged(newConfig);
}
https://developer.android.com/guide/topics/manifest/activity-element.html#config
I think the question is switching language in runtime for the app and displaying localized messages in UI. android:configChanges="locale" calls onConfigurationChanged if the system locale is changed (in setting of your device) while the app is running, and not if you change locale in the code for your app, which I guess is what you want to accomplish. That's why it's not refreshing.
Here is the method I use during every activity onCreate() or onResume() depending on my needs (if my activity will be resuming after user changed language settings or will always be created with language already set):
From there I just refresh the view manually or from onConfigurationChanged() which get called after this method finishes.
public static void changeLocale(Activity activity, String language)
{
final Resources res = activity.getResources();
final Configuration conf = res.getConfiguration();
if (language == null || language.length() == 0)
{
conf.locale = Locale.getDefault();
}
else
{
final int idx = language.indexOf('-');
if (idx != -1)
{
final String[] split = language.split("-");
conf.locale = new Locale(split[0], split[1].substring(1));
}
else
{
conf.locale = new Locale(language);
}
}
res.updateConfiguration(conf, null);
}
I'm not sure why this isn't picked up by onConfigurationChanged().
Hey, sandis, do you mean the method onConfigurationChanged() doesn't called in your activity when you changed the language? I met the same problem. The problem maybe this: when we change the language, the activity goes to onDestroy()(you can try this), so there is nobody to call onConfigurationChanged(). When we launch the activity again, the onCreate() is called, not the onConfigurationChanged(). There maybe something different in locale change and orientation change.
public void settingLocale(Context context, String language) {
Locale locale;
Configuration config = new Configuration();
if(language.equals(LANGUAGE_ENGLISH)) {
locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
}else if(language.equals(LANGUAGE_ARABIC)){
locale = new Locale("hi");
Locale.setDefault(locale);
config.locale = locale;
}
context.getResources().updateConfiguration(config, null);
// Here again set the text on view to reflect locale change
// and it will pick resource from new locale
tv1.setText(R.string.one); //tv1 is textview in my activity
}
Assuming you're changing the language through something like
private void updateLocale(#NonNull final Context context,
#NonNull final Locale newLocale) {
final Resources resources = context.getResources();
final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
final Configuration configuration = resources.getConfiguration();
configuration.locale = newLocale;
resources.updateConfiguration(configuration, displayMetrics);
Locale.setDefault(newLocale);
}
You'll need to call Activity.recreate() in all currently open activities, which is what would happen if the user changed the system language while you were not subscribing to android:configChanges="locale".