Add locale settings

This commit is contained in:
topjohnwu 2017-07-22 22:14:02 +08:00
parent c325deb4ed
commit bd6585765e
9 changed files with 157 additions and 4 deletions

View File

@ -5,22 +5,27 @@ import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.database.RepoDatabaseHelper; import com.topjohnwu.magisk.database.RepoDatabaseHelper;
import com.topjohnwu.magisk.database.SuDatabaseHelper; import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.module.Module; import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.utils.CallbackEvent; import com.topjohnwu.magisk.utils.CallbackEvent;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.SafetyNetHelper; import com.topjohnwu.magisk.utils.SafetyNetHelper;
import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
public class MagiskManager extends Application { public class MagiskManager extends Application {
@ -45,6 +50,7 @@ public class MagiskManager extends Application {
public final CallbackEvent<Void> repoLoadDone = new CallbackEvent<>(); public final CallbackEvent<Void> repoLoadDone = new CallbackEvent<>();
public final CallbackEvent<Void> updateCheckDone = new CallbackEvent<>(); public final CallbackEvent<Void> updateCheckDone = new CallbackEvent<>();
public final CallbackEvent<Void> safetyNetDone = new CallbackEvent<>(); public final CallbackEvent<Void> safetyNetDone = new CallbackEvent<>();
public final CallbackEvent<Void> localeDone = new CallbackEvent<>();
// Info // Info
public String magiskVersionString; public String magiskVersionString;
@ -65,10 +71,13 @@ public class MagiskManager extends Application {
// Data // Data
public Map<String, Module> moduleMap; public Map<String, Module> moduleMap;
public List<String> blockList; public List<String> blockList;
public List<Locale> locales;
// Configurations // Configurations
public static boolean shellLogging; public static boolean shellLogging;
public static boolean devLogging; public static boolean devLogging;
public static Locale locale;
public static Locale defaultLocale;
public boolean magiskHide; public boolean magiskHide;
public boolean isDarkTheme; public boolean isDarkTheme;
@ -90,6 +99,37 @@ public class MagiskManager extends Application {
private static Handler mHandler = new Handler(); private static Handler mHandler = new Handler();
private static class LoadLocale extends ParallelTask<Void, Void, Void> {
LoadLocale(Context context) {
super(context);
}
@Override
protected Void doInBackground(Void... voids) {
getMagiskManager().locales = Utils.getAvailableLocale(getMagiskManager());
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
getMagiskManager().localeDone.trigger();
}
}
public void setLocale() {
String localeTag = prefs.getString("locale", "");
if (localeTag.isEmpty()) {
locale = defaultLocale;
} else {
locale = Locale.forLanguageTag(localeTag);
}
Resources res = getBaseContext().getResources();
Configuration config = new Configuration(res.getConfiguration());
config.setLocale(locale);
res.updateConfiguration(config, res.getDisplayMetrics());
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -98,6 +138,9 @@ public class MagiskManager extends Application {
shell = Shell.getShell(); shell = Shell.getShell();
suDB = new SuDatabaseHelper(this); suDB = new SuDatabaseHelper(this);
repoDB = new RepoDatabaseHelper(this); repoDB = new RepoDatabaseHelper(this);
defaultLocale = Locale.getDefault();
setLocale();
new LoadLocale(this).exec();
} }
public void toast(String msg, int duration) { public void toast(String msg, int duration) {
@ -117,7 +160,6 @@ public class MagiskManager extends Application {
devLogging = false; devLogging = false;
shellLogging = false; shellLogging = false;
} }
magiskHide = prefs.getBoolean("magiskhide", true);
initSU(); initSU();
updateMagiskInfo(); updateMagiskInfo();
updateBlockInfo(); updateBlockInfo();

View File

@ -15,10 +15,13 @@ import android.widget.Toast;
import com.topjohnwu.magisk.components.Activity; import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.database.SuDatabaseHelper; import com.topjohnwu.magisk.database.SuDatabaseHelper;
import com.topjohnwu.magisk.utils.CallbackEvent;
import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import java.util.Locale;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -55,13 +58,15 @@ public class SettingsActivity extends Activity {
} }
public static class SettingsFragment extends PreferenceFragment public static class SettingsFragment extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener { implements SharedPreferences.OnSharedPreferenceChangeListener,
CallbackEvent.Listener<Void>{
private SharedPreferences prefs; private SharedPreferences prefs;
private PreferenceScreen prefScreen; private PreferenceScreen prefScreen;
private ListPreference suAccess, autoRes, suNotification, requestTimeout, multiuserMode, namespaceMode; private ListPreference suAccess, autoRes, suNotification, requestTimeout, multiuserMode, namespaceMode;
private MagiskManager magiskManager; private MagiskManager magiskManager;
private PreferenceCategory generalCatagory;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -71,6 +76,7 @@ public class SettingsActivity extends Activity {
prefScreen = getPreferenceScreen(); prefScreen = getPreferenceScreen();
magiskManager = Utils.getMagiskManager(getActivity()); magiskManager = Utils.getMagiskManager(getActivity());
generalCatagory = (PreferenceCategory) findPreference("general");
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk"); PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser"); PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
PreferenceCategory developer = (PreferenceCategory) findPreference("developer"); PreferenceCategory developer = (PreferenceCategory) findPreference("developer");
@ -118,16 +124,41 @@ public class SettingsActivity extends Activity {
} }
} }
private ListPreference setLocalePreference(ListPreference lp) {
if (lp == null) {
lp = new ListPreference(getActivity());
}
CharSequence[] entries = new CharSequence[magiskManager.locales.size() + 1];
CharSequence[] entryValues = new CharSequence[magiskManager.locales.size() + 1];
entries[0] = getString(R.string.system_default);
entryValues[0] = "";
int i = 1;
for (Locale locale : magiskManager.locales) {
entries[i] = locale.getDisplayName(locale);
entryValues[i++] = locale.toLanguageTag();
}
lp.setEntries(entries);
lp.setEntryValues(entryValues);
lp.setTitle(R.string.language);
lp.setKey("locale");
lp.setSummary(MagiskManager.locale.getDisplayName(MagiskManager.locale));
return lp;
}
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
prefs.registerOnSharedPreferenceChangeListener(this); prefs.registerOnSharedPreferenceChangeListener(this);
magiskManager.localeDone.register(this);
if (magiskManager.localeDone.isTriggered)
onTrigger(null);
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
prefs.unregisterOnSharedPreferenceChangeListener(this); prefs.unregisterOnSharedPreferenceChangeListener(this);
magiskManager.localeDone.unRegister(this);
} }
@Override @Override
@ -200,6 +231,11 @@ public class SettingsActivity extends Activity {
case "shell_logging": case "shell_logging":
MagiskManager.shellLogging = prefs.getBoolean("shell_logging", false); MagiskManager.shellLogging = prefs.getBoolean("shell_logging", false);
break; break;
case "locale":
magiskManager.setLocale();
magiskManager.reloadMainActivity.trigger();
getActivity().recreate();
break;
} }
setSummary(); setSummary();
} }
@ -218,6 +254,16 @@ public class SettingsActivity extends Activity {
namespaceMode.setSummary(getResources() namespaceMode.setSummary(getResources()
.getStringArray(R.array.namespace_summary)[magiskManager.suNamespaceMode]); .getStringArray(R.array.namespace_summary)[magiskManager.suNamespaceMode]);
} }
@Override
public void onTrigger(CallbackEvent<Void> event) {
ListPreference language = setLocalePreference(null);
language.setOnPreferenceClickListener((pref) -> {
setLocalePreference((ListPreference) pref);
return false;
});
generalCatagory.addPreference(language);
}
} }
} }

View File

@ -1,13 +1,24 @@
package com.topjohnwu.magisk.components; package com.topjohnwu.magisk.components;
import android.content.res.Configuration;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager; import android.view.WindowManager;
import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils;
import java.util.Locale;
public class Activity extends AppCompatActivity { public class Activity extends AppCompatActivity {
public Activity() {
super();
Configuration configuration = new Configuration();
configuration.setLocale(MagiskManager.locale);
applyOverrideConfiguration(configuration);
}
@Override @Override
public MagiskManager getApplicationContext() { public MagiskManager getApplicationContext() {
return (MagiskManager) super.getApplicationContext(); return (MagiskManager) super.getApplicationContext();

View File

@ -5,6 +5,8 @@ import android.database.Cursor;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.topjohnwu.magisk.MagiskManager;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
@ -48,11 +50,11 @@ public class SuLogEntry implements Parcelable {
} }
public String getDateString() { public String getDateString() {
return DateFormat.getDateInstance(DateFormat.MEDIUM).format(date); return DateFormat.getDateInstance(DateFormat.MEDIUM, MagiskManager.locale).format(date);
} }
public String getTimeString() { public String getTimeString() {
return new SimpleDateFormat("h:mm a", Locale.US).format(date); return new SimpleDateFormat("h:mm a", MagiskManager.locale).format(date);
} }

View File

@ -10,18 +10,23 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor; import android.database.Cursor;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
import android.support.annotation.IdRes;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.TaskStackBuilder; import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.NotificationCompat; import android.support.v7.app.NotificationCompat;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.MagiskManager;
@ -33,7 +38,12 @@ import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.receivers.ManagerUpdate; import com.topjohnwu.magisk.receivers.ManagerUpdate;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale;
public class Utils { public class Utils {
@ -246,4 +256,40 @@ public class Utils {
public static void rmMagiskHide(Shell shell, String pkg) { public static void rmMagiskHide(Shell shell, String pkg) {
shell.su_raw("magiskhide --rm " + pkg); shell.su_raw("magiskhide --rm " + pkg);
} }
public static String getLocaleString(Context context, Locale locale, @StringRes int id) {
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
Context localizedContext = context.createConfigurationContext(config);
return localizedContext.getString(id);
}
public static List<Locale> getAvailableLocale(Context context) {
List<Locale> locales = new ArrayList<>();
HashSet<String> set = new HashSet<>();
Locale locale;
// Add default locale
locales.add(Locale.ENGLISH);
set.add(getLocaleString(context, Locale.ENGLISH, R.string.download));
// Add some special locales
locales.add(Locale.TAIWAN);
set.add(getLocaleString(context, Locale.TAIWAN, R.string.download));
locale = new Locale("pt", "BR");
locales.add(locale);
set.add(getLocaleString(context, locale, R.string.download));
// Other locales
for (String s : context.getAssets().getLocales()) {
locale = Locale.forLanguageTag(s);
if (set.add(getLocaleString(context, locale, R.string.download))) {
locales.add(locale);
}
}
Collections.sort(locales, (l1, l2) -> l1.getDisplayName(l1).compareTo(l2.getDisplayName(l2)));
return locales;
}
} }

View File

@ -192,5 +192,6 @@
<string name="pid">PID:\u0020</string> <string name="pid">PID:\u0020</string>
<string name="target_uid">대상 UID:\u0020</string> <string name="target_uid">대상 UID:\u0020</string>
<string name="command">명령:\u0020</string> <string name="command">명령:\u0020</string>
<string name="download">다운로드</string>
</resources> </resources>

View File

@ -219,5 +219,7 @@
<string name="reinstall">重新安裝</string> <string name="reinstall">重新安裝</string>
<string name="update">更新</string> <string name="update">更新</string>
<string name="magisk_updates">Magisk 更新</string> <string name="magisk_updates">Magisk 更新</string>
<string name="system_default">(系統預設)</string>
<string name="language">語言</string>
</resources> </resources>

View File

@ -145,6 +145,8 @@
<string name="settings_notification_summary">Show update notifications when new version is available</string> <string name="settings_notification_summary">Show update notifications when new version is available</string>
<string name="settings_clear_cache_title">Clear Repo Cache</string> <string name="settings_clear_cache_title">Clear Repo Cache</string>
<string name="settings_clear_cache_summary">Clear the cached information for online repos, forces the app to refresh online</string> <string name="settings_clear_cache_summary">Clear the cached information for online repos, forces the app to refresh online</string>
<string name="language">Language</string>
<string name="system_default">(System Default)</string>
<string name="settings_core_only_title">Magisk Core Only Mode</string> <string name="settings_core_only_title">Magisk Core Only Mode</string>
<string name="settings_core_only_summary">Enable only core features, all modules will not be loaded. MagiskSU, MagiskHide, and systemless hosts will still be enabled</string> <string name="settings_core_only_summary">Enable only core features, all modules will not be loaded. MagiskSU, MagiskHide, and systemless hosts will still be enabled</string>

View File

@ -2,6 +2,7 @@
android:layout_marginTop="?attr/actionBarSize" android:layout_marginTop="?attr/actionBarSize"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory <PreferenceCategory
android:key="general"
android:title="@string/settings_general_category"> android:title="@string/settings_general_category">
<SwitchPreference <SwitchPreference