运行时本地化(多语言)在某些设备上不起作用。 Oppo f9 和华为 y9
RunTime Localization (Multi-language) not working on some devices ex. Oppo f9 and Huawei y9
我实现了以下本地化逻辑,以便能够动态地将我的应用程序的语言从英语更改为阿拉伯语,反之亦然。它适用于从 5.1 到 9.0 的所有模拟器版本,以及我所有的 7 台物理设备。
问题 是我收到了专门使用 Oppo f9 和华为 y9 (2019) 等设备的用户的抱怨,他们在尝试更改语言时布局方向发生了变化,但是该应用程序不使用其他字符串资源。它总是英文!
我对此失去了理智,我错过了什么吗?
public class App extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleManager.setLocale(base));
}
//Handles screen rotation only up till API 28 pie
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleManager.setLocale(this);
if (Build.VERSION.SDK_INT >= 26) {
ProcessPhoenix.triggerRebirth(this); //Restart app!
}
}
}
public class BaseActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Manager.isFirstLaunch(this)) { //Check if it is the first time to launch the app
startActivity(new Intent(this, ChooseLanguageActivity.class));
finish();
} else {
if (Build.VERSION.SDK_INT >= 26) {
LocaleManager.setLocale(this);
}
startActivity(new Intent(this, AuthenticationActivity.class));
finish();
}
}
}
public class ChooseLanguageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_language);
Crashlytics.log("ChooseLanguageActivity created");
}
public void EnglishButton(View view) {
LocaleManager.persistLanguage(this, "en"); //In case the mobile locale is Arabic for API >=Oreo
LocaleManager.setLocale(this);
Manager.firstLaunchCompleted(this);
ProcessPhoenix.triggerRebirth(this); //Restart app!
finish();
}
public void ArabicButton(View view) {
LocaleManager.persistLanguage(this, "ar");
LocaleManager.setLocale(this);
Manager.firstLaunchCompleted(this);
ProcessPhoenix.triggerRebirth(this); //Restart app!
finish();
}
}
public class LocaleManager {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
private static final String DEFAULT_LANGUAGE = "en";
public static Context setLocale(Context c) {
return setNewLocale(c, getLanguage(c));
}
public static Context setNewLocale(Context c, String language) {
persistLanguage(c, language);
return updateResources(c, language);
}
public static String getLanguage(Context c) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(c);
return preferences.getString(SELECTED_LANGUAGE, DEFAULT_LANGUAGE);
}
public static void persistLanguage(Context c, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.commit(); //U must use Commit and not apply, to avoid opening a new thread, causing a delayed writting in a separate thread!
Manager.appLanguage=language;//edited upon lang selection screen/future app launches/lang change through menu
}
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if(Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
}
我能够通过 生成一个签名的 APK 来解决这个问题(就像我在签名包存在之前通常做的那样),然后将它上传到 google 播放。
使用 生成签名包 在某些设备上从 google play 下载应用程序时会导致此问题,而其他设备则没有问题,因此令人困惑。
我的应用程序大小不知何故增加了 3MB,但至少当用户从 google 播放下载它时,它现在可以在所有设备上正常运行(我的和抱怨的用户的设备有问题)
我实现了以下本地化逻辑,以便能够动态地将我的应用程序的语言从英语更改为阿拉伯语,反之亦然。它适用于从 5.1 到 9.0 的所有模拟器版本,以及我所有的 7 台物理设备。
问题 是我收到了专门使用 Oppo f9 和华为 y9 (2019) 等设备的用户的抱怨,他们在尝试更改语言时布局方向发生了变化,但是该应用程序不使用其他字符串资源。它总是英文!
我对此失去了理智,我错过了什么吗?
public class App extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleManager.setLocale(base));
}
//Handles screen rotation only up till API 28 pie
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleManager.setLocale(this);
if (Build.VERSION.SDK_INT >= 26) {
ProcessPhoenix.triggerRebirth(this); //Restart app!
}
}
}
public class BaseActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Manager.isFirstLaunch(this)) { //Check if it is the first time to launch the app
startActivity(new Intent(this, ChooseLanguageActivity.class));
finish();
} else {
if (Build.VERSION.SDK_INT >= 26) {
LocaleManager.setLocale(this);
}
startActivity(new Intent(this, AuthenticationActivity.class));
finish();
}
}
}
public class ChooseLanguageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_choose_language);
Crashlytics.log("ChooseLanguageActivity created");
}
public void EnglishButton(View view) {
LocaleManager.persistLanguage(this, "en"); //In case the mobile locale is Arabic for API >=Oreo
LocaleManager.setLocale(this);
Manager.firstLaunchCompleted(this);
ProcessPhoenix.triggerRebirth(this); //Restart app!
finish();
}
public void ArabicButton(View view) {
LocaleManager.persistLanguage(this, "ar");
LocaleManager.setLocale(this);
Manager.firstLaunchCompleted(this);
ProcessPhoenix.triggerRebirth(this); //Restart app!
finish();
}
}
public class LocaleManager {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
private static final String DEFAULT_LANGUAGE = "en";
public static Context setLocale(Context c) {
return setNewLocale(c, getLanguage(c));
}
public static Context setNewLocale(Context c, String language) {
persistLanguage(c, language);
return updateResources(c, language);
}
public static String getLanguage(Context c) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(c);
return preferences.getString(SELECTED_LANGUAGE, DEFAULT_LANGUAGE);
}
public static void persistLanguage(Context c, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.commit(); //U must use Commit and not apply, to avoid opening a new thread, causing a delayed writting in a separate thread!
Manager.appLanguage=language;//edited upon lang selection screen/future app launches/lang change through menu
}
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = new Configuration(res.getConfiguration());
if(Build.VERSION.SDK_INT >= 17) {
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
return context;
}
}
我能够通过 生成一个签名的 APK 来解决这个问题(就像我在签名包存在之前通常做的那样),然后将它上传到 google 播放。
使用 生成签名包 在某些设备上从 google play 下载应用程序时会导致此问题,而其他设备则没有问题,因此令人困惑。
我的应用程序大小不知何故增加了 3MB,但至少当用户从 google 播放下载它时,它现在可以在所有设备上正常运行(我的和抱怨的用户的设备有问题)