Fixed issue #226 - preferences don't crash.

Use custom code rather than "Locale.forLanguageTag" (which is android-21
specific). Also fixed the actual setting of the language, by modifying
the code in FDroidApp to respect the country code (rather than just the
language code).
This commit is contained in:
Peter Serwylo 2015-04-15 11:26:06 +10:00
parent f69985d8df
commit de3e34060c
4 changed files with 38 additions and 14 deletions

View File

@ -38,8 +38,7 @@
<item>cs</item>
<item>de</item>
<item>el</item>
<item>en-rGB</item>
<item>en-US</item>
<item>en-rUS</item>
<item>eo</item>
<item>es</item>
<item>eu</item>

View File

@ -141,11 +141,9 @@ public class FDroidApp extends Application {
}
public static void updateLanguage(Context c, String lang) {
Configuration cfg = new Configuration();
if (!TextUtils.isEmpty(lang))
cfg.locale = new Locale(lang);
else
cfg.locale = Locale.getDefault();
final Configuration cfg = new Configuration();
final Locale newLocale = Utils.getLocaleFromAndroidLangTag(lang);
cfg.locale = newLocale == null ? Locale.getDefault() : newLocale;
c.getResources().updateConfiguration(cfg, null);
}

View File

@ -371,6 +371,36 @@ public final class Utils {
return ret;
}
/**
* There is a method {@link java.util.Locale#forLanguageTag(String)} which would be useful
* for this, however it doesn't deal with android-specific language tags, which are a little
* different. For example, android language tags may have an "r" before the country code,
* such as "zh-rHK", however {@link java.util.Locale} expects them to be "zr-HK".
*/
public static Locale getLocaleFromAndroidLangTag(String languageTag) {
if (TextUtils.isEmpty(languageTag)) {
return null;
}
final String[] parts = languageTag.split("-");
if (parts.length == 1) {
return new Locale(parts[0]);
} else if (parts.length == 2) {
String country = parts[1];
// Some languages have an "r" before the country as per the values folders, such
// as "zh-rCN". As far as the Locale class is concerned, the "r" is
// not helpful, and this should be "zh-CN". Thus, we will
// strip the "r" when found.
if (country.charAt(0) == 'r' && country.length() == 3) {
country = country.substring(1);
}
return new Locale(parts[0], country);
} else {
Log.e(TAG, "Locale could not be parsed from language tag: " + languageTag);
return new Locale(languageTag);
}
}
public static class CommaSeparatedList implements Iterable<String> {
private final String value;

View File

@ -14,6 +14,7 @@ import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.PreferencesActivity;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.installer.CheckRootAsyncTask;
import org.fdroid.fdroid.installer.Installer;
@ -293,17 +294,13 @@ public class PreferencesFragment extends PreferenceFragment
}
private void langSpinner(String key) {
ListPreference pref = (ListPreference)findPreference(key);
final ListPreference pref = (ListPreference)findPreference(key);
final String[] langValues = getResources().getStringArray(R.array.languageValues);
String[] langNames = new String[langValues.length];
langNames[0] = getString(R.string.pref_language_default);
for (int i = 1; i < langValues.length; i++) {
try {
final Locale appLoc = Locale.forLanguageTag(langValues[i]);
langNames[i] = appLoc.getDisplayName(appLoc);
} catch (Exception e) {
langNames[i] = langValues[i];
}
final Locale appLoc = Utils.getLocaleFromAndroidLangTag(langValues[i]);
langNames[i] = appLoc == null ? langValues[i] : appLoc.getDisplayName(appLoc);
}
pref.setEntries(langNames);
}