Improve locale settings

This commit is contained in:
topjohnwu 2018-08-01 14:16:44 +08:00
parent e90c555c18
commit 8574a14ed2
8 changed files with 113 additions and 114 deletions

View File

@ -1,6 +1,7 @@
package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
@ -24,6 +25,7 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
private Unbinder unbinder;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
SearchView search;
private ApplicationAdapter appAdapter;
@ -37,14 +39,14 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false);
unbinder = ButterKnife.bind(this, view);
mSwipeRefreshLayout.setRefreshing(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> appAdapter.refresh());
mSwipeRefreshLayout.setOnRefreshListener(appAdapter::refresh);
appAdapter = new ApplicationAdapter();
appAdapter = new ApplicationAdapter(requireActivity());
recyclerView.setAdapter(appAdapter);
searchListener = new SearchView.OnQueryTextListener() {
@ -61,7 +63,7 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
}
};
getActivity().setTitle(R.string.magiskhide);
requireActivity().setTitle(R.string.magiskhide);
return view;
}
@ -69,7 +71,7 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_magiskhide, menu);
SearchView search = (SearchView) menu.findItem(R.id.app_search).getActionView();
search = (SearchView) menu.findItem(R.id.app_search).getActionView();
search.setOnQueryTextListener(searchListener);
}
@ -87,6 +89,6 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
@Override
public void onPublish(int topic, Object[] result) {
mSwipeRefreshLayout.setRefreshing(false);
appAdapter.filter(null);
appAdapter.filter(search.getQuery().toString());
}
}

View File

@ -2,6 +2,7 @@ package com.topjohnwu.magisk;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.preference.PreferenceManager;
import android.text.TextUtils;
@ -14,7 +15,6 @@ import com.topjohnwu.superuser.ContainerApp;
import com.topjohnwu.superuser.Shell;
import java.lang.ref.WeakReference;
import java.util.Locale;
import java.util.Map;
public class MagiskManager extends ContainerApp {
@ -58,8 +58,13 @@ public class MagiskManager extends ContainerApp {
} catch (PackageManager.NameNotFoundException ignored) {}
}
LocaleManager.setLocale();
LocaleManager.setLocale(this);
Data.loadConfig();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleManager.setLocale(this);
}
}

View File

@ -283,7 +283,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
mm.mDB.setSettings(key, Utils.getPrefsInt(prefs, key));
break;
case Const.Key.LOCALE:
LocaleManager.setLocale();
LocaleManager.setLocale(mm);
Topic.publish(false, Topic.RELOAD_ACTIVITY);
break;
case Const.Key.UPDATE_CHANNEL:

View File

@ -31,7 +31,7 @@ public class SplashActivity extends Activity {
Data.importPrefs();
// Dynamic detect all locales
new LocaleManager.LoadLocale().exec();
LocaleManager.loadAvailableLocales();
// Create notification channel on Android O
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

View File

@ -1,7 +1,12 @@
package com.topjohnwu.magisk.adapters;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
@ -13,9 +18,8 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.utils.LocaleManager;
import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.superuser.Shell;
@ -34,26 +38,63 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
private PackageManager pm;
private ApplicationFilter filter;
public ApplicationAdapter() {
public ApplicationAdapter(Context context) {
fullList = showList = Collections.emptyList();
hideList = Collections.emptyList();
filter = new ApplicationFilter();
pm = Data.MM().getPackageManager();
new LoadApps().exec();
pm = context.getPackageManager();
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
return new ViewHolder(v);
}
private String getLabel(ApplicationInfo info) {
if (info.labelRes > 0) {
try {
Resources res = pm.getResourcesForApplication(info);
Configuration config = new Configuration();
config.setLocale(LocaleManager.locale);
res.updateConfiguration(config, res.getDisplayMetrics());
return res.getString(info.labelRes);
} catch (PackageManager.NameNotFoundException ignored) { /* Impossible */ }
}
return info.loadLabel(pm).toString();
}
private void loadApps() {
fullList = pm.getInstalledApplications(0);
hideList = Shell.su("magiskhide --ls").exec().getOut();
for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
i.remove();
}
}
Collections.sort(fullList, (a, b) -> {
boolean ah = hideList.contains(a.packageName);
boolean bh = hideList.contains(b.packageName);
if (ah == bh) {
return getLabel(a).toLowerCase().compareTo(getLabel(b).toLowerCase());
} else if (ah) {
return -1;
} else {
return 1;
}
});
Topic.publish(false, Topic.MAGISK_HIDE_DONE);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
return new ViewHolder(mView);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ApplicationInfo info = showList.get(position);
holder.appIcon.setImageDrawable(info.loadIcon(pm));
holder.appName.setText(info.loadLabel(pm));
holder.appName.setText(getLabel(info));
holder.appPackage.setText(info.packageName);
holder.checkBox.setOnCheckedChangeListener(null);
@ -79,7 +120,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
}
public void refresh() {
new LoadApps().exec();
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
}
static class ViewHolder extends RecyclerView.ViewHolder {
@ -109,7 +150,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
showList = new ArrayList<>();
String filter = constraint.toString().toLowerCase();
for (ApplicationInfo info : fullList) {
if (lowercaseContains(info.loadLabel(pm).toString(), filter)
if (lowercaseContains(getLabel(info), filter)
|| lowercaseContains(info.packageName, filter)) {
showList.add(info);
}
@ -123,37 +164,4 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
notifyDataSetChanged();
}
}
private class LoadApps extends ParallelTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
fullList = pm.getInstalledApplications(0);
hideList = Shell.su("magiskhide --ls").exec().getOut();
for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
i.remove();
}
}
Collections.sort(fullList, (a, b) -> {
boolean ah = hideList.contains(a.packageName);
boolean bh = hideList.contains(b.packageName);
if (ah == bh) {
return a.loadLabel(pm).toString().toLowerCase().compareTo(
b.loadLabel(pm).toString().toLowerCase());
} else if (ah) {
return -1;
} else {
return 1;
}
});
return null;
}
@Override
protected void onPostExecute(Void v) {
Topic.publish(false, Topic.MAGISK_HIDE_DONE);
}
}
}

View File

@ -1,5 +1,6 @@
package com.topjohnwu.magisk.components;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
@ -19,11 +20,12 @@ public abstract class FlavorActivity extends AppCompatActivity implements Topic.
private ActivityResultListener activityResultListener;
static int[] EMPTY_INT_ARRAY = new int[0];
public FlavorActivity() {
super();
Configuration configuration = new Configuration();
configuration.setLocale(LocaleManager.locale);
applyOverrideConfiguration(configuration);
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Configuration config = base.getResources().getConfiguration();
config.setLocale(LocaleManager.locale);
applyOverrideConfiguration(config);
}
@Override

View File

@ -25,7 +25,7 @@ public class SuReceiver extends BroadcastReceiver {
String command, action;
Policy policy;
MagiskManager mm = Utils.getMagiskManager(context);
MagiskManager mm = Data.MM();
if (intent == null) return;
@ -47,7 +47,7 @@ public class SuReceiver extends BroadcastReceiver {
policy = mm.mDB.getPolicy(fromUid);
if (policy == null) {
try {
policy = new Policy(fromUid, context.getPackageManager());
policy = new Policy(fromUid, mm.getPackageManager());
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return;
@ -59,20 +59,19 @@ public class SuReceiver extends BroadcastReceiver {
String message;
switch (action) {
case "allow":
message = context.getString(R.string.su_allow_toast, policy.appName);
message = mm.getString(R.string.su_allow_toast, policy.appName);
log.action = true;
break;
case "deny":
message = context.getString(R.string.su_deny_toast, policy.appName);
message = mm.getString(R.string.su_deny_toast, policy.appName);
log.action = false;
break;
default:
return;
}
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST) {
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST)
Utils.toast(message, Toast.LENGTH_SHORT);
}
if (mode == Const.Value.NOTIFY_NORMAL_LOG && policy.logging) {
toUid = intent.getIntExtra("to.uid", -1);

View File

@ -2,13 +2,13 @@ package com.topjohnwu.magisk.utils;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.support.annotation.StringRes;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import java.util.ArrayList;
import java.util.Collections;
@ -21,14 +21,14 @@ public class LocaleManager {
public final static Locale defaultLocale = Locale.getDefault();
public static List<Locale> locales;
public static void setLocale() {
MagiskManager mm = Data.MM();
public static void setLocale(MagiskManager mm) {
String localeConfig = mm.prefs.getString(Const.Key.LOCALE, "");
if (localeConfig.isEmpty()) {
locale = defaultLocale;
} else {
locale = Locale.forLanguageTag(localeConfig);
}
Locale.setDefault(locale);
Resources res = mm.getResources();
Configuration config = res.getConfiguration();
config.setLocale(locale);
@ -36,58 +36,41 @@ public class LocaleManager {
}
public static String getString(Locale locale, @StringRes int id) {
Configuration config = Data.MM().getResources().getConfiguration();
Configuration config = new Configuration();
config.setLocale(locale);
return getString(config, id);
}
private static String getString(Configuration config, @StringRes int id) {
return Data.MM().createConfigurationContext(config).getString(id);
}
private static List<Locale> getAvailableLocale() {
List<Locale> locales = new ArrayList<>();
HashSet<String> set = new HashSet<>();
MagiskManager mm = Data.MM();
Locale locale;
public static void loadAvailableLocales() {
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
locales = new ArrayList<>();
HashSet<String> set = new HashSet<>();
Resources res = Data.MM().getResources();
Locale locale;
@StringRes int compareId = R.string.download_file_error;
@StringRes int compareId = R.string.download_file_error;
// Add default locale
locales.add(Locale.ENGLISH);
set.add(getString(Locale.ENGLISH, compareId));
// Add default locale
locales.add(Locale.ENGLISH);
set.add(getString(Locale.ENGLISH, compareId));
// Add some special locales
locales.add(Locale.TAIWAN);
set.add(getString(Locale.TAIWAN, compareId));
locale = new Locale("pt", "BR");
locales.add(locale);
set.add(getString(locale, compareId));
// Add some special locales
locales.add(Locale.TAIWAN);
set.add(getString(Locale.TAIWAN, compareId));
locale = new Locale("pt", "BR");
locales.add(locale);
set.add(getString(locale, compareId));
// Other locales
Configuration config = mm.getResources().getConfiguration();
for (String s : mm.getAssets().getLocales()) {
locale = Locale.forLanguageTag(s);
config.setLocale(locale);
if (set.add(getString(config, compareId))) {
locales.add(locale);
// Other locales
for (String s : res.getAssets().getLocales()) {
locale = Locale.forLanguageTag(s);
if (set.add(getString(locale, compareId))) {
locales.add(locale);
}
}
}
Collections.sort(locales, (a, b) -> a.getDisplayName(a).compareTo(b.getDisplayName(b)));
return locales;
}
public static class LoadLocale extends ParallelTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
locales = getAvailableLocale();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
Collections.sort(locales, (a, b) -> a.getDisplayName(a).compareTo(b.getDisplayName(b)));
Topic.publish(Topic.LOCAL_FETCH_DONE);
}
});
}
}