mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-22 20:31:16 +00:00
Add preference to change app language (fixes #742)
This commit is contained in:
parent
6718811c29
commit
e8073599ae
6 changed files with 231 additions and 1 deletions
|
@ -24,7 +24,8 @@
|
||||||
android:theme="@style/Theme.Syncthing"
|
android:theme="@style/Theme.Syncthing"
|
||||||
android:description="@string/app_description"
|
android:description="@string/app_description"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:installLocation="internalOnly">
|
android:installLocation="internalOnly"
|
||||||
|
android:name=".SyncthingApp">
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.FirstStartActivity"
|
android:name=".activities.FirstStartActivity"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
|
|
14
src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java
Normal file
14
src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package com.nutomic.syncthingandroid;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.util.Languages;
|
||||||
|
|
||||||
|
public class SyncthingApp extends Application {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
new Languages(this).setLanguage(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
||||||
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
|
@ -22,6 +23,7 @@ import com.nutomic.syncthingandroid.model.Device;
|
||||||
import com.nutomic.syncthingandroid.model.Options;
|
import com.nutomic.syncthingandroid.model.Options;
|
||||||
import com.nutomic.syncthingandroid.service.RestApi;
|
import com.nutomic.syncthingandroid.service.RestApi;
|
||||||
import com.nutomic.syncthingandroid.service.SyncthingService;
|
import com.nutomic.syncthingandroid.service.SyncthingService;
|
||||||
|
import com.nutomic.syncthingandroid.util.Languages;
|
||||||
import com.nutomic.syncthingandroid.views.WifiSsidPreference;
|
import com.nutomic.syncthingandroid.views.WifiSsidPreference;
|
||||||
|
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
|
@ -105,6 +107,16 @@ public class SettingsActivity extends SyncthingActivity {
|
||||||
mSyncOnlyWifi.setEnabled(mAlwaysRunInBackground.isChecked());
|
mSyncOnlyWifi.setEnabled(mAlwaysRunInBackground.isChecked());
|
||||||
mSyncOnlyOnSSIDs.setEnabled(mSyncOnlyWifi.isChecked());
|
mSyncOnlyOnSSIDs.setEnabled(mSyncOnlyWifi.isChecked());
|
||||||
|
|
||||||
|
ListPreference languagePref = (ListPreference) findPreference(Languages.PREFERENCE_LANGUAGE);
|
||||||
|
Languages languages = new Languages(getActivity());
|
||||||
|
languagePref.setDefaultValue(Languages.USE_SYSTEM_DEFAULT);
|
||||||
|
languagePref.setEntries(languages.getAllNames());
|
||||||
|
languagePref.setEntryValues(languages.getSupportedLocales());
|
||||||
|
languagePref.setOnPreferenceChangeListener((p, o) -> {
|
||||||
|
languages.forceChangeLanguage(getActivity(), (String) o);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
mDeviceName = (EditTextPreference) findPreference("deviceName");
|
mDeviceName = (EditTextPreference) findPreference("deviceName");
|
||||||
mListenAddresses = (EditTextPreference) findPreference("listenAddresses");
|
mListenAddresses = (EditTextPreference) findPreference("listenAddresses");
|
||||||
mMaxRecvKbps = (EditTextPreference) findPreference("maxRecvKbps");
|
mMaxRecvKbps = (EditTextPreference) findPreference("maxRecvKbps");
|
||||||
|
|
192
src/main/java/com/nutomic/syncthingandroid/util/Languages.java
Normal file
192
src/main/java/com/nutomic/syncthingandroid/util/Languages.java
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
package com.nutomic.syncthingandroid.util;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.nutomic.syncthingandroid.R;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Based on https://gitlab.com/fdroid/fdroidclient/blob/master/app/src/main/java/org/fdroid/fdroid/Languages.java
|
||||||
|
*/
|
||||||
|
public final class Languages {
|
||||||
|
public static final String TAG = "Languages";
|
||||||
|
|
||||||
|
public static final String USE_SYSTEM_DEFAULT = "";
|
||||||
|
|
||||||
|
private static final Locale DEFAULT_LOCALE;
|
||||||
|
public static final String PREFERENCE_LANGUAGE = "pref_current_language";
|
||||||
|
|
||||||
|
private final SharedPreferences mPreferences;
|
||||||
|
private static Map<String, String> mAvailableLanguages;
|
||||||
|
|
||||||
|
static {
|
||||||
|
DEFAULT_LOCALE = Locale.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Languages(Context context) {
|
||||||
|
Map<String, String> tmpMap = new TreeMap<>();
|
||||||
|
for (Locale locale : Arrays.asList(LOCALES_TO_TEST)) {
|
||||||
|
tmpMap.put(locale.getLanguage(), locale.getDisplayLanguage(locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the current system language from the menu
|
||||||
|
tmpMap.remove(Locale.getDefault().getLanguage());
|
||||||
|
|
||||||
|
/* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */
|
||||||
|
tmpMap.put(USE_SYSTEM_DEFAULT, context.getString(R.string.pref_language_default));
|
||||||
|
mAvailableLanguages = Collections.unmodifiableMap(tmpMap);
|
||||||
|
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles setting the language if it is different than the current language,
|
||||||
|
* or different than the current system-wide locale. The preference is cleared
|
||||||
|
* if the language matches the system-wide locale or "System Default" is chosen.
|
||||||
|
*/
|
||||||
|
@TargetApi(17)
|
||||||
|
public void setLanguage(Context context) {
|
||||||
|
if (Build.VERSION.SDK_INT >= 24) {
|
||||||
|
Log.d(TAG, "Languages.setLanguage() ignored on >= android-24");
|
||||||
|
mPreferences.edit().remove(PREFERENCE_LANGUAGE).apply();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String language = mPreferences.getString(PREFERENCE_LANGUAGE, null);
|
||||||
|
Locale locale;
|
||||||
|
if (TextUtils.equals(language, DEFAULT_LOCALE.getLanguage())) {
|
||||||
|
mPreferences.edit().remove(PREFERENCE_LANGUAGE).apply();
|
||||||
|
locale = DEFAULT_LOCALE;
|
||||||
|
} else if (language == null || language.equals(USE_SYSTEM_DEFAULT)) {
|
||||||
|
mPreferences.edit().remove(PREFERENCE_LANGUAGE).apply();
|
||||||
|
locale = DEFAULT_LOCALE;
|
||||||
|
} else {
|
||||||
|
/* handle locales with the country in it, i.e. zh_CN, zh_TW, etc */
|
||||||
|
String[] localeSplit = language.split("_");
|
||||||
|
if (localeSplit.length > 1) {
|
||||||
|
locale = new Locale(localeSplit[0], localeSplit[1]);
|
||||||
|
} else {
|
||||||
|
locale = new Locale(language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Locale.setDefault(locale);
|
||||||
|
|
||||||
|
final Resources resources = context.getResources();
|
||||||
|
Configuration config = resources.getConfiguration();
|
||||||
|
if (Build.VERSION.SDK_INT >= 17) {
|
||||||
|
config.setLocale(locale);
|
||||||
|
} else {
|
||||||
|
config.locale = locale;
|
||||||
|
}
|
||||||
|
resources.updateConfiguration(config, resources.getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force reload the {@link Activity to make language changes take effect.}
|
||||||
|
*
|
||||||
|
* @param activity the {@code Activity} to force reload
|
||||||
|
*/
|
||||||
|
@SuppressLint("ApplySharedPref")
|
||||||
|
public void forceChangeLanguage(Activity activity, String newLanguage) {
|
||||||
|
mPreferences.edit().putString(PREFERENCE_LANGUAGE, newLanguage).commit();
|
||||||
|
setLanguage(activity);
|
||||||
|
if (Build.VERSION.SDK_INT >= 24) {
|
||||||
|
Log.d(TAG, "Languages.forceChangeLanguage() ignored on >= android-24");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent intent = activity.getIntent();
|
||||||
|
if (intent == null) { // when launched as LAUNCHER
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||||
|
activity.finish();
|
||||||
|
activity.overridePendingTransition(0, 0);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
activity.overridePendingTransition(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an array of the names of all the supported languages, sorted to
|
||||||
|
* match what is returned by {@link Languages#getSupportedLocales()}.
|
||||||
|
*/
|
||||||
|
public String[] getAllNames() {
|
||||||
|
return mAvailableLanguages.values().toArray(new String[mAvailableLanguages.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return sorted list of supported locales.
|
||||||
|
*/
|
||||||
|
public String[] getSupportedLocales() {
|
||||||
|
Set<String> keys = mAvailableLanguages.keySet();
|
||||||
|
return keys.toArray(new String[keys.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String capitalize(final String line) {
|
||||||
|
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Locale[] LOCALES_TO_TEST = {
|
||||||
|
Locale.ENGLISH,
|
||||||
|
Locale.FRENCH,
|
||||||
|
Locale.GERMAN,
|
||||||
|
Locale.ITALIAN,
|
||||||
|
Locale.JAPANESE,
|
||||||
|
Locale.KOREAN,
|
||||||
|
Locale.SIMPLIFIED_CHINESE,
|
||||||
|
Locale.TRADITIONAL_CHINESE,
|
||||||
|
new Locale("af"),
|
||||||
|
new Locale("ar"),
|
||||||
|
new Locale("be"),
|
||||||
|
new Locale("bg"),
|
||||||
|
new Locale("ca"),
|
||||||
|
new Locale("cs"),
|
||||||
|
new Locale("da"),
|
||||||
|
new Locale("el"),
|
||||||
|
new Locale("es"),
|
||||||
|
new Locale("eo"),
|
||||||
|
new Locale("et"),
|
||||||
|
new Locale("eu"),
|
||||||
|
new Locale("fa"),
|
||||||
|
new Locale("fi"),
|
||||||
|
new Locale("he"),
|
||||||
|
new Locale("hi"),
|
||||||
|
new Locale("hu"),
|
||||||
|
new Locale("hy"),
|
||||||
|
new Locale("id"),
|
||||||
|
new Locale("is"),
|
||||||
|
new Locale("it"),
|
||||||
|
new Locale("ml"),
|
||||||
|
new Locale("my"),
|
||||||
|
new Locale("nb"),
|
||||||
|
new Locale("nl"),
|
||||||
|
new Locale("pl"),
|
||||||
|
new Locale("pt"),
|
||||||
|
new Locale("ro"),
|
||||||
|
new Locale("ru"),
|
||||||
|
new Locale("sc"),
|
||||||
|
new Locale("sk"),
|
||||||
|
new Locale("sn"),
|
||||||
|
new Locale("sr"),
|
||||||
|
new Locale("sv"),
|
||||||
|
new Locale("th"),
|
||||||
|
new Locale("tr"),
|
||||||
|
new Locale("uk"),
|
||||||
|
new Locale("vi"),
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -271,6 +271,12 @@ Please report any problems you encounter via Github.</string>
|
||||||
<item>None</item>
|
<item>None</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string name="preference_language_title">Language</string>
|
||||||
|
|
||||||
|
<string name="preference_language_summary">Change the app language</string>
|
||||||
|
|
||||||
|
<string name="pref_language_default">Default Language</string>
|
||||||
|
|
||||||
<string-array name="versioning_types">
|
<string-array name="versioning_types">
|
||||||
<item>None</item>
|
<item>None</item>
|
||||||
<item>TrashCan</item>
|
<item>TrashCan</item>
|
||||||
|
|
|
@ -49,6 +49,11 @@
|
||||||
android:summary="@string/notification_type_summary"
|
android:summary="@string/notification_type_summary"
|
||||||
android:defaultValue="low_priority" />
|
android:defaultValue="low_priority" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="pref_current_language"
|
||||||
|
android:title="@string/preference_language_title"
|
||||||
|
android:summary="@string/preference_language_summary" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
|
|
Loading…
Reference in a new issue