This commit is contained in:
NekoInverter 2020-03-13 11:46:11 +08:00
parent 1f109b37b8
commit 9d8f2f98e7
No known key found for this signature in database
GPG Key ID: 280D6CCCF95715F9
37 changed files with 4276 additions and 122 deletions

View File

@ -5,14 +5,33 @@ android {
viewBinding {
enabled = true
}
signingConfigs {
def keystorePwd = null
def alias = null
def pwd = null
if (project.rootProject.file('local.properties').exists()) {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
keystorePwd = properties.getProperty("RELEASE_STORE_PASSWORD")
alias = properties.getProperty("RELEASE_KEY_ALIAS")
pwd = properties.getProperty("RELEASE_KEY_PASSWORD")
}
release {
storeFile file("edxpmanager.jks")
storePassword keystorePwd != null ? keystorePwd : System.getenv("KEYSTORE_PASS")
keyAlias alias != null ? alias : System.getenv("ALIAS_NAME")
keyPassword pwd != null ? pwd : System.getenv("ALIAS_PASS")
}
}
compileSdkVersion 28
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "org.meowcat.edxposed.manager"
minSdkVersion 26
//noinspection OldTargetApi
targetSdkVersion 27
versionCode 45408
versionName "4.5.4.4"
versionCode 45409
versionName "4.5.4.5"
}
buildTypes {
release {
@ -21,9 +40,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
minifyEnabled false
shrinkResources false
signingConfig signingConfigs.release
}
}
compileOptions {
@ -45,6 +64,7 @@ dependencies {
implementation 'com.google.android.material:material:1.2.0-alpha05'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.takisoft.preferencex:preferencex:1.1.0'
implementation 'com.takisoft.preferencex:preferencex-colorpicker:1.1.0'
implementation 'com.takisoft.preferencex:preferencex-simplemenu:1.1.0'
implementation 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
}

BIN
app/edxpmanager.jks Normal file

Binary file not shown.

View File

@ -4,10 +4,10 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import androidx.appcompat.app.ActionBar;
import androidx.core.text.HtmlCompat;
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -43,7 +43,7 @@ public class AboutActivity extends BaseActivity {
} else {
binding.changelogView.setOnClickListener(v1 -> new MaterialAlertDialogBuilder(this)
.setTitle(R.string.changes)
.setMessage(Html.fromHtml(changes))
.setMessage(HtmlCompat.fromHtml(changes, HtmlCompat.FROM_HTML_MODE_LEGACY))
.setPositiveButton(android.R.string.ok, null).show());
}

View File

@ -5,7 +5,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Looper;
import android.text.TextUtils;
@ -24,6 +23,8 @@ import androidx.core.view.ViewCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.topjohnwu.superuser.Shell;
import org.meowcat.edxposed.manager.util.CustomThemeColor;
import org.meowcat.edxposed.manager.util.CustomThemeColors;
import org.meowcat.edxposed.manager.util.NavUtil;
import java.util.LinkedList;
@ -49,8 +50,12 @@ public class BaseActivity extends AppCompatActivity {
return THEME_DEFAULT;
}
public static boolean isNightMode(Configuration configuration) {
return (configuration.uiMode & Configuration.UI_MODE_NIGHT_YES) > 0;
}
@StyleRes
public static int getThemeStyleRes(Context context) {
public int getThemeStyleRes(Context context) {
switch (getTheme(context)) {
case THEME_BLACK:
return R.style.ThemeOverlay_Black;
@ -60,8 +65,27 @@ public class BaseActivity extends AppCompatActivity {
}
}
public static boolean isNightMode(Configuration configuration) {
return (configuration.uiMode & Configuration.UI_MODE_NIGHT_YES) > 0;
@StyleRes
private int getCustomTheme() {
String baseThemeName = XposedApp.getPreferences().getBoolean("colorized_action_bar", false) ?
"ThemeOverlay.ActionBarPrimaryColor" : "ThemeOverlay";
String customThemeName;
String primaryColorEntryName = "colorPrimary";
for (CustomThemeColor color : CustomThemeColors.Primary.values()) {
if (XposedApp.getPreferences().getInt("primary_color", ContextCompat.getColor(this, R.color.colorPrimary))
== ContextCompat.getColor(this, color.getResourceId())) {
primaryColorEntryName = color.getResourceEntryName();
}
}
String accentColorEntryName = "colorAccent";
for (CustomThemeColor color : CustomThemeColors.Accent.values()) {
if (XposedApp.getPreferences().getInt("accent_color", ContextCompat.getColor(this, R.color.colorAccent))
== ContextCompat.getColor(this, color.getResourceId())) {
accentColorEntryName = color.getResourceEntryName();
}
}
customThemeName = baseThemeName + "." + primaryColorEntryName + "." + accentColorEntryName;
return getResources().getIdentifier(customThemeName, "style", getPackageName());
}
protected void setupWindowInsets(View rootView, View secondView) {
@ -85,13 +109,13 @@ public class BaseActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
if (!(this instanceof MainActivity) && getWindow().getStatusBarColor() != Color.BLACK) {
/*if (!(this instanceof MainActivity) && getWindow().getStatusBarColor() != Color.BLACK) {
if (XposedApp.getPreferences().getBoolean("transparent_status_bar", false)) {
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.colorActionBar));
} else {
getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
}
}
}*/
if (!Objects.equals(mTheme, getTheme(this))) {
recreate();
}
@ -110,6 +134,9 @@ public class BaseActivity extends AppCompatActivity {
}
theme.applyStyle(resid, false);
}
if (!(this instanceof MainActivity)) {
theme.applyStyle(getCustomTheme(), true);
}
theme.applyStyle(getThemeStyleRes(this), true);
// only pass theme style to super, so styled theme will not be overwritten
super.onApplyThemeResource(theme, R.style.ThemeOverlay, first);

View File

@ -5,7 +5,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -14,6 +13,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.text.HtmlCompat;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -26,7 +26,7 @@ import org.meowcat.edxposed.manager.util.json.XposedZip;
import java.util.Objects;
public class BaseAdvancedInstaller extends Fragment {
SingleInstallerViewBinding binding;
private SingleInstallerViewBinding binding;
static BaseAdvancedInstaller newInstance(XposedTab tab) {
BaseAdvancedInstaller myFragment = new BaseAdvancedInstaller();
@ -98,7 +98,7 @@ public class BaseAdvancedInstaller extends Fragment {
startActivity(intent);
}));
binding.noticeTv.setText(Html.fromHtml(tab.notice));
binding.noticeTv.setText(HtmlCompat.fromHtml(tab.notice, HtmlCompat.FROM_HTML_MODE_LEGACY));
binding.author.setText(getString(R.string.download_author, tab.author));
try {
@ -121,7 +121,7 @@ public class BaseAdvancedInstaller extends Fragment {
binding.showOnXda.setOnClickListener(v -> NavUtil.startURL((AppCompatActivity) getActivity(), tab.support));
binding.updateDescription.setOnClickListener(v -> new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext()))
.setTitle(R.string.changes)
.setMessage(Html.fromHtml(tab.description))
.setMessage(HtmlCompat.fromHtml(tab.description, HtmlCompat.FROM_HTML_MODE_LEGACY))
.setPositiveButton(android.R.string.ok, null).show());
return binding.getRoot();

View File

@ -22,6 +22,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.SearchView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -337,12 +338,12 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
txtStatus.setText(context.getString(
R.string.download_status_update_available,
installedVersion, latestVersion));
txtStatus.setTextColor(getResources().getColor(R.color.download_status_update_available));
txtStatus.setTextColor(ContextCompat.getColor(DownloadActivity.this, R.color.download_status_update_available));
txtStatus.setVisibility(View.VISIBLE);
} else if (isInstalled) {
txtStatus.setText(context.getString(
R.string.download_status_installed, installedVersion));
txtStatus.setTextColor(getResources().getColor(R.color.warning));
txtStatus.setTextColor(ContextCompat.getColor(DownloadActivity.this, R.color.warning));
TypedArray typedArray = DownloadActivity.this.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorHighlight});
int textColor = typedArray.getColor(0, 0);
typedArray.recycle();

View File

@ -68,7 +68,7 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
if (!repoLoader.isVersionShown(module.versions.get(0))) {
TextView txtHeader = new TextView(getActivity());
txtHeader.setText(R.string.download_test_version_not_shown);
txtHeader.setTextColor(getResources().getColor(R.color.warning));
txtHeader.setTextColor(ContextCompat.getColor(activity, R.color.warning));
txtHeader.setOnClickListener(v -> activity.gotoPage(DownloadDetailsActivity.DOWNLOAD_SETTINGS));
getListView().addHeaderView(txtHeader);
}
@ -213,9 +213,9 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
int color = ContextCompat.getColor(context, typedValue.resourceId);
colorRelTypeStable = color;
colorRelTypeOthers = getResources().getColor(R.color.warning);
colorRelTypeOthers = ContextCompat.getColor(activity, R.color.warning);
colorInstalled = color;
colorUpdateAvailable = getResources().getColor(R.color.download_status_update_available);
colorUpdateAvailable = ContextCompat.getColor(activity, R.color.download_status_update_available);
textInstalled = getString(R.string.download_section_installed) + ":";
textUpdateAvailable = getString(R.string.download_section_update_available) + ":";
installedVersionCode = (installed != null) ? installed.versionCode : -1;

View File

@ -1,5 +1,6 @@
package org.meowcat.edxposed.manager;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Build;
@ -65,13 +66,10 @@ public class EdDownloadActivity extends BaseActivity {
@Override
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
getMenuInflater().inflate(R.menu.menu_installer, menu);
if (Build.VERSION.SDK_INT < 26) {
menu.findItem(R.id.dexopt_all).setVisible(false);
menu.findItem(R.id.speed_all).setVisible(false);
}
return super.onCreateOptionsMenu(menu);
}
@SuppressLint("StaticFieldLeak")
private class JSONParser extends AsyncTask<Void, Void, String> {
@Override

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.content.ContextCompat;
import org.meowcat.edxposed.manager.databinding.ActivityMainBinding;
import org.meowcat.edxposed.manager.util.ModuleUtil;
@ -79,18 +80,18 @@ public class MainActivity extends BaseActivity implements RepoLoader.RepoListene
String installedXposedVersionStr = installedXposedVersionInt + ".0";
binding.statusTitle.setText(R.string.Activated);
binding.statusSummary.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
binding.status.setCardBackgroundColor(getResources().getColor(R.color.download_status_update_available));
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.download_status_update_available));
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_check_circle));
} else {
binding.statusTitle.setText(R.string.Inactivate);
binding.statusSummary.setText(R.string.installed_lollipop_inactive);
binding.status.setCardBackgroundColor(getResources().getColor(R.color.amber_500));
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.amber_500));
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_warning));
}
} else {
binding.statusTitle.setText(R.string.Install);
binding.statusSummary.setText(R.string.InstallDetail);
binding.status.setCardBackgroundColor(getResources().getColor(R.color.colorPrimary));
binding.status.setCardBackgroundColor(ContextCompat.getColor(this, R.color.colorPrimary));
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_error));
}
notifyDataSetChanged();

View File

@ -1,6 +1,7 @@
package org.meowcat.edxposed.manager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@ -19,6 +20,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -47,7 +49,8 @@ import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@ -64,16 +67,18 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
private int installedXposedVersion;
private ApplicationFilter filter;
private SearchView searchView;
private ApplicationInfo.DisplayNameComparator displayNameComparator;
private SearchView.OnQueryTextListener mSearchListener;
private PackageManager pm;
private Comparator<ApplicationInfo> cmp;
private DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
private ModuleUtil moduleUtil;
private ModuleAdapter adapter = null;
private Runnable reloadModules = new Runnable() {
public void run() {
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
Collection<ModuleUtil.InstalledModule> showList;
Collection<ModuleUtil.InstalledModule> fullList = moduleUtil.getModules().values();
ArrayList<ModuleUtil.InstalledModule> showList;
ArrayList<ModuleUtil.InstalledModule> fullList = new ArrayList<>(moduleUtil.getModules().values());
if (queryStr.length() == 0) {
showList = fullList;
} else {
@ -86,6 +91,72 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
}
}
switch (XposedApp.getPreferences().getInt("list_sort", 0)) {
case 7:
cmp = Collections.reverseOrder((ApplicationInfo a, ApplicationInfo b) -> {
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).lastUpdateTime, pm.getPackageInfo(b.packageName, 0).lastUpdateTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
});
break;
case 6:
cmp = (ApplicationInfo a, ApplicationInfo b) -> {
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).lastUpdateTime, pm.getPackageInfo(b.packageName, 0).lastUpdateTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
};
break;
case 5:
cmp = Collections.reverseOrder((ApplicationInfo a, ApplicationInfo b) -> {
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).firstInstallTime, pm.getPackageInfo(b.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
});
break;
case 4:
cmp = (ApplicationInfo a, ApplicationInfo b) -> {
try {
return Long.compare(pm.getPackageInfo(a.packageName, 0).firstInstallTime, pm.getPackageInfo(b.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return displayNameComparator.compare(a, b);
}
};
break;
case 3:
cmp = Collections.reverseOrder((a, b) -> a.packageName.compareTo(b.packageName));
break;
case 2:
cmp = (a, b) -> a.packageName.compareTo(b.packageName);
break;
case 1:
cmp = Collections.reverseOrder(displayNameComparator);
break;
case 0:
default:
cmp = displayNameComparator;
break;
}
Collections.sort(fullList, (a, b) -> {
boolean aChecked = moduleUtil.isModuleEnabled(a.packageName);
boolean bChecked = moduleUtil.isModuleEnabled(b.packageName);
if (aChecked == bChecked) {
return cmp.compare(a.app, b.app);
} else if (aChecked) {
return -1;
} else {
return 1;
}
});
adapter.addAll(showList);
TransitionManager.beginDelayedTransition(binding.recyclerView);
adapter.notifyDataSetChanged();
@ -114,6 +185,8 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
filter = new ApplicationFilter();
moduleUtil = ModuleUtil.getInstance();
pm = getPackageManager();
displayNameComparator = new ApplicationInfo.DisplayNameComparator(pm);
cmp = displayNameComparator;
installedXposedVersion = XposedApp.getXposedVersion();
if (installedXposedVersion <= 0) {
Snackbar.make(binding.snackbar, R.string.xposed_not_active, Snackbar.LENGTH_LONG).setAction(R.string.Settings, v -> {
@ -409,7 +482,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
private class ModuleAdapter extends RecyclerView.Adapter<ModuleAdapter.ViewHolder> {
Collection<ModuleUtil.InstalledModule> items;
ArrayList<ModuleUtil.InstalledModule> items = new ArrayList<>();
@NonNull
@Override
@ -420,7 +493,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ModuleUtil.InstalledModule item = (ModuleUtil.InstalledModule) items.toArray()[position];
ModuleUtil.InstalledModule item = items.get(position);
holder.itemView.setOnClickListener(v -> {
String packageName = item.packageName;
if (packageName == null) {
@ -476,7 +549,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
descriptionText.setText(item.getDescription());
} else {
descriptionText.setText(getString(R.string.module_empty_description));
descriptionText.setTextColor(getResources().getColor(R.color.warning));
descriptionText.setTextColor(ContextCompat.getColor(ModulesActivity.this, R.color.warning));
}
SwitchCompat mSwitch = holder.mSwitch;
@ -527,7 +600,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
}
void addAll(Collection<ModuleUtil.InstalledModule> items) {
void addAll(ArrayList<ModuleUtil.InstalledModule> items) {
this.items = items;
notifyDataSetChanged();
}

View File

@ -2,11 +2,13 @@ package org.meowcat.edxposed.manager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.FileUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@ -16,7 +18,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.preference.Preference;
import androidx.preference.SwitchPreferenceCompat;
@ -35,10 +36,27 @@ import java.io.FileOutputStream;
import java.io.IOException;
public class SettingsActivity extends BaseActivity {
private static final String KEY_PREFIX = SettingsActivity.class.getName() + '.';
private static final String EXTRA_SAVED_INSTANCE_STATE = KEY_PREFIX + "SAVED_INSTANCE_STATE";
ActivitySettingsBinding binding;
private boolean restarting;
@NonNull
public static Intent newIntent(@NonNull Context context) {
return new Intent(context, SettingsActivity.class);
}
@NonNull
private static Intent newIntent(@NonNull Bundle savedInstanceState, @NonNull Context context) {
return newIntent(context)
.putExtra(EXTRA_SAVED_INSTANCE_STATE, savedInstanceState);
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
savedInstanceState = getIntent().getBundleExtra(EXTRA_SAVED_INSTANCE_STATE);
}
super.onCreate(savedInstanceState);
binding = ActivitySettingsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
@ -56,6 +74,41 @@ public class SettingsActivity extends BaseActivity {
}
private void restart() {
Bundle savedInstanceState = new Bundle();
onSaveInstanceState(savedInstanceState);
finish();
startActivity(newIntent(savedInstanceState, this));
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
restarting = true;
}
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
return restarting || super.dispatchKeyEvent(event);
}
@SuppressLint("RestrictedApi")
@Override
public boolean dispatchKeyShortcutEvent(@NonNull KeyEvent event) {
return restarting || super.dispatchKeyShortcutEvent(event);
}
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchTouchEvent(event);
}
@Override
public boolean dispatchTrackballEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchTrackballEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(@NonNull MotionEvent event) {
return restarting || super.dispatchGenericMotionEvent(event);
}
@SuppressWarnings({"ResultOfMethodCallIgnored", "deprecation"})
public static class SettingsFragment extends PreferenceFragmentCompat {
static final File disableResourcesFlag = new File(XposedApp.BASE_DIR + "conf/disable_resources");
@ -69,13 +122,13 @@ public class SettingsActivity extends BaseActivity {
static final File modulesLogProcessID = new File(XposedApp.BASE_DIR + "log/error.pid");
@SuppressLint({"WorldReadableFiles", "WorldWriteableFiles"})
static void setFilePermissionsFromMode(String name, int mode) {
static void setFilePermissionsFromMode(String name) {
int perms = FileUtils.S_IRUSR | FileUtils.S_IWUSR
| FileUtils.S_IRGRP | FileUtils.S_IWGRP;
if ((mode & MODE_WORLD_READABLE) != 0) {
if ((MODE_WORLD_READABLE) != 0) {
perms |= FileUtils.S_IROTH;
}
if ((mode & MODE_WORLD_WRITEABLE) != 0) {
if ((Context.MODE_WORLD_READABLE & MODE_WORLD_WRITEABLE) != 0) {
perms |= FileUtils.S_IWOTH;
}
FileUtils.setPermissions(name, perms, -1, -1);
@ -118,7 +171,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(whiteListModeFlag.getPath());
setFilePermissionsFromMode(whiteListModeFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(whiteListModeFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -151,7 +204,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(disableVerboseLogsFlag.getPath());
setFilePermissionsFromMode(disableVerboseLogsFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(disableVerboseLogsFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -184,7 +237,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(disableModulesLogsFlag.getPath());
setFilePermissionsFromMode(disableModulesLogsFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(disableModulesLogsFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -217,7 +270,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(blackWhiteListModeFlag.getPath());
setFilePermissionsFromMode(blackWhiteListModeFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(blackWhiteListModeFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -250,7 +303,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(deoptBootFlag.getPath());
setFilePermissionsFromMode(deoptBootFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(deoptBootFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -283,7 +336,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(dynamicModulesFlag.getPath());
setFilePermissionsFromMode(dynamicModulesFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(dynamicModulesFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -316,7 +369,7 @@ public class SettingsActivity extends BaseActivity {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(disableResourcesFlag.getPath());
setFilePermissionsFromMode(disableResourcesFlag.getPath(), MODE_WORLD_READABLE);
setFilePermissionsFromMode(disableResourcesFlag.getPath());
} catch (FileNotFoundException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
@ -340,7 +393,7 @@ public class SettingsActivity extends BaseActivity {
});
}
SwitchPreferenceCompat transparent = findPreference("transparent_status_bar");
/*SwitchPreferenceCompat transparent = findPreference("transparent_status_bar");
if (transparent != null) {
transparent.setOnPreferenceChangeListener((preference, newValue) -> {
boolean enabled = (Boolean) newValue;
@ -354,7 +407,7 @@ public class SettingsActivity extends BaseActivity {
}
return true;
});
}
}*/
Preference compat_mode = findPreference("compat_mode");
if (compat_mode != null) {
@ -380,9 +433,42 @@ public class SettingsActivity extends BaseActivity {
SwitchPreferenceCompat black_dark_theme = findPreference("black_dark_theme");
if (black_dark_theme != null) {
black_dark_theme.setOnPreferenceChangeListener((preference, newValue) -> {
Activity activity = getActivity();
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null && isNightMode(getResources().getConfiguration())) {
activity.restart();
}
return true;
});
}
Preference primary_color = findPreference("primary_color");
if (primary_color != null) {
primary_color.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.recreate();
activity.restart();
}
return true;
});
}
Preference accent_color = findPreference("accent_color");
if (accent_color != null) {
accent_color.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null) {
activity.restart();
}
return true;
});
}
Preference colorized_action_bar = findPreference("colorized_action_bar");
if (colorized_action_bar != null) {
colorized_action_bar.setOnPreferenceChangeListener((preference, newValue) -> {
SettingsActivity activity = (SettingsActivity) getActivity();
if (activity != null && !(isBlackNightTheme() && isNightMode(getResources().getConfiguration()))) {
activity.restart();
}
return true;
});

View File

@ -6,7 +6,6 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@ -14,6 +13,8 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -38,7 +39,7 @@ public class StatusInstallerFragment extends Fragment {
binding.clickToUpdate.setVisibility(View.VISIBLE);
binding.clickToUpdate.setOnClickListener(v -> new MaterialAlertDialogBuilder(context)
.setTitle(R.string.changes)
.setMessage(Html.fromHtml(changelog))
.setMessage(HtmlCompat.fromHtml(changelog, HtmlCompat.FROM_HTML_MODE_LEGACY))
.setPositiveButton(R.string.update, (dialog, which) -> update(context))
.setNegativeButton(R.string.later, null).show());
}
@ -134,13 +135,13 @@ public class StatusInstallerFragment extends Fragment {
if (verified) {
binding.dmverity.setText(R.string.verified_boot_active);
binding.dmverity.setTextColor(getResources().getColor(R.color.warning));
binding.dmverity.setTextColor(ContextCompat.getColor(requireActivity(), R.color.warning));
} else if (detected) {
binding.dmverity.setText(R.string.verified_boot_deactivated);
binding.dmverityExplanation.setVisibility(View.GONE);
} else {
binding.dmverity.setText(R.string.verified_boot_none);
binding.dmverity.setTextColor(getResources().getColor(R.color.warning));
binding.dmverity.setTextColor(ContextCompat.getColor(requireActivity(), R.color.warning));
binding.dmverityExplanation.setVisibility(View.GONE);
}
} catch (Exception e) {

View File

@ -8,14 +8,11 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import androidx.annotation.NonNull;
@ -34,19 +31,16 @@ import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import de.robv.android.xposed.installer.util.InstallZipUtil;
public class XposedApp extends de.robv.android.xposed.installer.XposedApp implements Application.ActivityLifecycleCallbacks {
public static final String TAG = "EdXposedManager";
public static final String BASE_DIR = "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/";
public static final String ENABLED_MODULES_LIST_FILE = "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/" + "conf/enabled_modules.list";
@SuppressLint("SdCardPath")
private static final String BASE_DIR_LEGACY = "/data/data/" + BuildConfig.APPLICATION_ID + "/";
public static final String BASE_DIR = Build.VERSION.SDK_INT >= 24
? "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/" : BASE_DIR_LEGACY;
public static final String ENABLED_MODULES_LIST_FILE = (Build.VERSION.SDK_INT >= 24
? "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/" : BASE_DIR_LEGACY) + "conf/enabled_modules.list";
@SuppressLint("StaticFieldLeak")
private static XposedApp instance = null;
private static Thread uiThread;
@ -143,14 +137,6 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
}
}
if (pref.getBoolean("force_english", false)) {
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = Locale.ENGLISH;
res.updateConfiguration(conf, dm);
}
RepoLoader.getInstance().triggerFirstLoadIfNecessary();
}
@ -184,15 +170,13 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
mkdirAndChmod("conf", 00777);
mkdirAndChmod("log", 00777);
if (Build.VERSION.SDK_INT >= 24) {
try {
@SuppressLint("SoonBlockedPrivateApi") Method deleteDir = FileUtils.class.getDeclaredMethod("deleteContentsAndDir", File.class);
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "bin"));
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "conf"));
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "log"));
} catch (ReflectiveOperationException e) {
Log.w(de.robv.android.xposed.installer.XposedApp.TAG, "Failed to delete obsolete directories", e);
}
try {
@SuppressLint("SoonBlockedPrivateApi") Method deleteDir = FileUtils.class.getDeclaredMethod("deleteContentsAndDir", File.class);
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "bin"));
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "conf"));
deleteDir.invoke(null, new File(BASE_DIR_LEGACY, "log"));
} catch (ReflectiveOperationException e) {
Log.w(de.robv.android.xposed.installer.XposedApp.TAG, "Failed to delete obsolete directories", e);
}
}

View File

@ -155,19 +155,16 @@ public class AppAdapter extends RecyclerView.Adapter<AppAdapter.ViewHolder> {
break;
}
Collections.sort(fullList, (a, b) -> {
if (XposedApp.getPreferences().getBoolean("enabled_top", true)) {
boolean aChecked = checkedList.contains(a.packageName);
boolean bChecked = checkedList.contains(b.packageName);
if (aChecked == bChecked) {
return cmp.compare(a, b);
} else if (aChecked) {
return -1;
} else {
return 1;
}
} else {
boolean aChecked = checkedList.contains(a.packageName);
boolean bChecked = checkedList.contains(b.packageName);
if (aChecked == bChecked) {
return cmp.compare(a, b);
} else if (aChecked) {
return -1;
} else {
return 1;
}
});
}

View File

@ -26,7 +26,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2019 Hai Zhang <dreaming.in.code.zh@gmail.com>
* All Rights Reserved.
*/
package org.meowcat.edxposed.manager.util;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
public interface CustomThemeColor {
@ColorRes
int getResourceId();
@NonNull
String getResourceEntryName();
}

View File

@ -0,0 +1,104 @@
package org.meowcat.edxposed.manager.util;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import org.meowcat.edxposed.manager.R;
public class CustomThemeColors {
private CustomThemeColors() {
}
public enum Primary implements CustomThemeColor {
COLORPRIMARY(R.color.colorPrimary, "colorPrimary"),
MATERIAL_RED_500(R.color.material_red_500, "material_red_500"),
MATERIAL_PINK_500(R.color.material_pink_500, "material_pink_500"),
MATERIAL_PURPLE_500(R.color.material_purple_500, "material_purple_500"),
MATERIAL_DEEP_PURPLE_500(R.color.material_deep_purple_500, "material_deep_purple_500"),
MATERIAL_INDIGO_500(R.color.material_indigo_500, "material_indigo_500"),
MATERIAL_BLUE_500(R.color.material_blue_500, "material_blue_500"),
MATERIAL_LIGHT_BLUE_500(R.color.material_light_blue_500, "material_light_blue_500"),
MATERIAL_CYAN_500(R.color.material_cyan_500, "material_cyan_500"),
MATERIAL_TEAL_500(R.color.material_teal_500, "material_teal_500"),
MATERIAL_GREEN_500(R.color.material_green_500, "material_green_500"),
MATERIAL_LIGHT_GREEN_500(R.color.material_light_green_500, "material_light_green_500"),
MATERIAL_LIME_500(R.color.material_lime_500, "material_lime_500"),
MATERIAL_YELLOW_500(R.color.material_yellow_500, "material_yellow_500"),
MATERIAL_AMBER_500(R.color.material_amber_500, "material_amber_500"),
MATERIAL_ORANGE_500(R.color.material_orange_500, "material_orange_500"),
MATERIAL_DEEP_ORANGE_500(R.color.material_deep_orange_500, "material_deep_orange_500"),
MATERIAL_BROWN_500(R.color.material_brown_500, "material_brown_500"),
MATERIAL_GREY_500(R.color.material_grey_500, "material_grey_500"),
MATERIAL_BLUE_GREY_500(R.color.material_blue_grey_500, "material_blue_grey_500");
@ColorRes
private final int mResourceId;
@NonNull
private final String mResourceEntryName;
Primary(@ColorRes int resourceId, @NonNull String resourceEntryName) {
mResourceId = resourceId;
mResourceEntryName = resourceEntryName;
}
@ColorRes
@Override
public int getResourceId() {
return mResourceId;
}
@NonNull
@Override
public String getResourceEntryName() {
return mResourceEntryName;
}
}
public enum Accent implements CustomThemeColor {
COLORACCENT(R.color.colorAccent, "colorAccent"),
MATERIAL_RED_A200(R.color.material_red_a200, "material_red_a200"),
MATERIAL_PINK_A200(R.color.material_pink_a200, "material_pink_a200"),
MATERIAL_PURPLE_A200(R.color.material_purple_a200, "material_purple_a200"),
MATERIAL_DEEP_PURPLE_A200(R.color.material_deep_purple_a200, "material_deep_purple_a200"),
MATERIAL_INDIGO_A200(R.color.material_indigo_a200, "material_indigo_a200"),
MATERIAL_BLUE_A200(R.color.material_blue_a200, "material_blue_a200"),
MATERIAL_LIGHT_BLUE_500(R.color.material_light_blue_500, "material_light_blue_500"),
MATERIAL_CYAN_500(R.color.material_cyan_500, "material_cyan_500"),
MATERIAL_TEAL_500(R.color.material_teal_500, "material_teal_500"),
MATERIAL_GREEN_500(R.color.material_green_500, "material_green_500"),
MATERIAL_LIGHT_GREEN_500(R.color.material_light_green_500, "material_light_green_500"),
MATERIAL_LIME_500(R.color.material_lime_500, "material_lime_500"),
MATERIAL_YELLOW_500(R.color.material_yellow_500, "material_yellow_500"),
MATERIAL_AMBER_500(R.color.material_amber_500, "material_amber_500"),
MATERIAL_ORANGE_500(R.color.material_orange_500, "material_orange_500"),
MATERIAL_DEEP_ORANGE_500(R.color.material_deep_orange_500, "material_deep_orange_500"),
MATERIAL_BROWN_500(R.color.material_brown_500, "material_brown_500"),
MATERIAL_GREY_500(R.color.material_grey_500, "material_grey_500"),
MATERIAL_BLUE_GREY_500(R.color.material_blue_grey_500, "material_blue_grey_500");
@ColorRes
private final int mResourceId;
@NonNull
private final String mResourceEntryName;
Accent(@ColorRes int resourceId, @NonNull String resourceEntryName) {
mResourceId = resourceId;
mResourceEntryName = resourceEntryName;
}
@ColorRes
@Override
public int getResourceId() {
return mResourceId;
}
@NonNull
@Override
public String getResourceEntryName() {
return mResourceEntryName;
}
}
}

View File

@ -0,0 +1,62 @@
package org.meowcat.edxposed.manager.widget;
import android.content.Context;
import android.util.AttributeSet;
import androidx.core.content.ContextCompat;
import com.takisoft.preferencex.ColorPickerPreference;
import com.takisoft.preferencex.ColorPickerPreferenceDialogFragmentCompat;
import com.takisoft.preferencex.PreferenceFragmentCompat;
import org.meowcat.edxposed.manager.util.CustomThemeColor;
import org.meowcat.edxposed.manager.util.CustomThemeColors;
import java.util.Objects;
public class ThemeColorPreference extends ColorPickerPreference {
static {
PreferenceFragmentCompat.registerPreferenceFragment(ThemeColorPreference.class,
ColorPickerPreferenceDialogFragmentCompat.class);
}
public ThemeColorPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public ThemeColorPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ThemeColorPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ThemeColorPreference(Context context) {
super(context);
init();
}
private void init() {
String key = getKey();
Context context = getContext();
CustomThemeColor[] colors;
if (Objects.equals(key, "primary_color")) {
colors = CustomThemeColors.Primary.values();
} else if (Objects.equals(key, "accent_color")) {
colors = CustomThemeColors.Accent.values();
} else {
throw new IllegalArgumentException("Unknown custom theme color preference key: " + key);
}
int[] mEntryValues = new int[colors.length];
for (int i = 0; i < colors.length; ++i) {
CustomThemeColor color = colors[i];
mEntryValues[i] = ContextCompat.getColor(context, color.getResourceId());
}
setColors(mEntryValues);
}
}

View File

@ -10,18 +10,18 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
android:theme="?actionBarTheme">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="?actionBarPopupTheme" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/sliding_tabs"
style="@style/Widget.MaterialComponents.TabLayout"
style="?tabLayoutTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorActionBar"

View File

@ -7,18 +7,18 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
android:theme="?actionBarTheme">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="?actionBarPopupTheme" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
style="@style/Widget.MaterialComponents.TabLayout"
style="?tabLayoutTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorActionBar"

View File

@ -10,18 +10,18 @@
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
android:theme="?actionBarTheme">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="?actionBarPopupTheme" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/sliding_tabs"
style="@style/Widget.MaterialComponents.TabLayout"
style="?tabLayoutTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorActionBar"

View File

@ -2,13 +2,13 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
android:theme="?actionBarTheme">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
app:popupTheme="?actionBarPopupTheme" />
</com.google.android.material.appbar.AppBarLayout>

View File

@ -1,14 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#2196f3</color>
<color name="colorBackground">#424242</color>
<color name="colorAccent">#448aff</color>
<color name="colorPrimary">@color/material_blue_700</color>
<color name="colorBackground">#303030</color>
<color name="colorPrimaryDark">#2E2E2E</color>
<color name="colorActionBar">#383838</color>
<color name="red_500">#F44336</color>
<color name="warning">@color/red_500</color>
<color name="download_status_update_available">#4CAF50</color>
<color name="amber_500">#FFC107</color>
<color name="navigationBarColor">#B3000000</color>
<color name="colorStickyHeader">#EA424242</color>
</resources>

View File

@ -0,0 +1,4 @@
<resources>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Dark" />
</resources>

View File

@ -288,4 +288,16 @@
<string name="pref_compat_mode_title">兼容模式</string>
<string name="xposed_not_active">EdXposed 框架未安装或未激活, 您可在设置中关闭状态检查</string>
<string name="transparent_status_bar">透明状态栏</string>
<string name="list_sort">列表排序方式</string>
<string name="sort_by_name">应用名称</string>
<string name="sort_by_name_reverse">应用名称(降序)</string>
<string name="sort_by_package_name">包体名称</string>
<string name="sort_by_package_name_reverse">包体名称(降序)</string>
<string name="sort_by_install_time">安装时间</string>
<string name="sort_by_install_time_reverse">安装时间(降序)</string>
<string name="sort_by_update_time">更新时间</string>
<string name="sort_by_update_time_reverse">更新时间(降序)</string>
<string name="primary_color">主要色</string>
<string name="accent_color">强调色</string>
<string name="colorized_action_bar">着色应用栏</string>
</resources>

View File

@ -108,7 +108,7 @@
<string name="settings_release_type">要顯示的版本</string>
<string name="settings_group_framework">框架</string>
<string name="settings_disable_resources">禁用資源鈎子</string>
<string name="settings_disable_resources_summary">解決與主題引擎的衝突\n<b>: </b> 啟用該選項將導致修改資源的模塊無法工作</string>
<string name="settings_disable_resources_summary">解決與主題引擎的衝突\n<b>: </b> 啟用該選項將導致修改資源的模塊無法工作</string>
<string name="settings_group_app">應用</string>
<string name="settings_theme">主題</string>
<string name="settings_theme_light">亮色</string>
@ -286,6 +286,18 @@
<string name="install_timestamps">安裝於 %1$s\n更新於 %2$s</string>
<string name="pref_compat_mode_summary">兼容模式應用列表</string>
<string name="pref_compat_mode_title">兼容模式</string>
<string name="xposed_not_active">EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查</string>
<string name="xposed_not_active">EdXposed 框架未安裝或未激活, 您可在設置中關閉狀態檢查</string>
<string name="transparent_status_bar">透明狀態欄</string>
<string name="list_sort">列表排序方式</string>
<string name="sort_by_name">應用名稱</string>
<string name="sort_by_name_reverse">應用名稱(降序)</string>
<string name="sort_by_package_name">包體名稱</string>
<string name="sort_by_package_name_reverse">包體名稱(降序)</string>
<string name="sort_by_install_time">安裝時間</string>
<string name="sort_by_install_time_reverse">安裝時間(降序)</string>
<string name="sort_by_update_time">更新時間</string>
<string name="sort_by_update_time_reverse">更新時間(降序)</string>
<string name="primary_color">主要色</string>
<string name="accent_color">強調色</string>
<string name="colorized_action_bar">着色應用欄</string>
</resources>

View File

@ -86,7 +86,7 @@
<string name="download_unknown_author">未知作者</string>
<string name="download_status_installed">已安裝(版本 %s)</string>
<string name="download_status_update_available">可更新(版本 %1$s \u2192 %2$s)</string>
<string name="download_timestamps">新增於 %1$s \u00b7 更新於 %2$s</string>
<string name="download_timestamps">添加於 %1$s \u00b7 更新於 %2$s</string>
<string name="download_sorting_title">排序方式</string>
<string name="download_sorting_status">按狀態排序</string>
<string name="download_sorting_updated">按最後更新排序</string>
@ -288,4 +288,16 @@
<string name="pref_compat_mode_title">相容模式</string>
<string name="xposed_not_active">EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查</string>
<string name="transparent_status_bar">透明狀態列</string>
<string name="list_sort">列表排序方式</string>
<string name="sort_by_name">應用名稱</string>
<string name="sort_by_name_reverse">應用名稱(降序)</string>
<string name="sort_by_package_name">包體名稱</string>
<string name="sort_by_package_name_reverse">包體名稱(降序)</string>
<string name="sort_by_install_time">安裝時間</string>
<string name="sort_by_install_time_reverse">安裝時間(降序)</string>
<string name="sort_by_update_time">更新時間</string>
<string name="sort_by_update_time_reverse">更新時間(降序)</string>
<string name="primary_color">主要色</string>
<string name="accent_color">強調色</string>
<string name="colorized_action_bar">著色應用欄</string>
</resources>

View File

@ -37,7 +37,27 @@
<item>@string/reltype_beta_summary</item>
<item>@string/reltype_experimental_summary</item>
</string-array>
<string-array name="list_sort_texts">
<item>@string/sort_by_name</item>
<item>@string/sort_by_name_reverse</item>
<item>@string/sort_by_package_name</item>
<item>@string/sort_by_package_name_reverse</item>
<item>@string/sort_by_install_time</item>
<item>@string/sort_by_install_time_reverse</item>
<item>@string/sort_by_update_time</item>
<item>@string/sort_by_update_time_reverse</item>
</string-array>
<string-array name="list_sort_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
</string-array>
<string-array name="module_release_type_values" translatable="false">
<item />
<item>stable</item>

View File

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="colorActionBar" format="color" />
<attr name="actionBarTheme" format="reference" />
<attr name="actionBarPopupTheme" format="reference" />
<attr name="tabLayoutTheme" format="reference" />
</resources>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#2196f3</color>
<color name="colorPrimary">@color/material_blue_700</color>
<color name="colorBackground">#fafafa</color>
<color name="colorPrimaryDark">#dddddd</color>
<color name="colorAccent">#448aff</color>
<color name="colorAccent">#e91e63</color>
<color name="colorActionBar">#F0F0F0</color>
<color name="red_500">#F44336</color>
<color name="warning">@color/red_500</color>

View File

@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="material_red_50">#FFEBEE</color>
<color name="material_red_100">#FFCDD2</color>
<color name="material_red_200">#EF9A9A</color>
<color name="material_red_300">#E57373</color>
<color name="material_red_400">#EF5350</color>
<color name="material_red_500">#F44336</color>
<color name="material_red_600">#E53935</color>
<color name="material_red_700">#D32F2F</color>
<color name="material_red_800">#C62828</color>
<color name="material_red_900">#B71C1C</color>
<color name="material_red_a100">#FF8A80</color>
<color name="material_red_a200">#FF5252</color>
<color name="material_red_a400">#FF1744</color>
<color name="material_red_a700">#D50000</color>
<color name="material_pink_50">#FCE4EC</color>
<color name="material_pink_100">#F8BBD0</color>
<color name="material_pink_200">#F48FB1</color>
<color name="material_pink_300">#F06292</color>
<color name="material_pink_400">#EC407A</color>
<color name="material_pink_500">#E91E63</color>
<color name="material_pink_600">#D81B60</color>
<color name="material_pink_700">#C2185B</color>
<color name="material_pink_800">#AD1457</color>
<color name="material_pink_900">#880E4F</color>
<color name="material_pink_a100">#FF80AB</color>
<color name="material_pink_a200">#FF4081</color>
<color name="material_pink_a400">#F50057</color>
<color name="material_pink_a700">#C51162</color>
<color name="material_purple_50">#F3E5F5</color>
<color name="material_purple_100">#E1BEE7</color>
<color name="material_purple_200">#CE93D8</color>
<color name="material_purple_300">#BA68C8</color>
<color name="material_purple_400">#AB47BC</color>
<color name="material_purple_500">#9C27B0</color>
<color name="material_purple_600">#8E24AA</color>
<color name="material_purple_700">#7B1FA2</color>
<color name="material_purple_800">#6A1B9A</color>
<color name="material_purple_900">#4A148C</color>
<color name="material_purple_a100">#EA80FC</color>
<color name="material_purple_a200">#E040FB</color>
<color name="material_purple_a400">#D500F9</color>
<color name="material_purple_a700">#AA00FF</color>
<color name="material_deep_purple_50">#EDE7F6</color>
<color name="material_deep_purple_100">#D1C4E9</color>
<color name="material_deep_purple_200">#B39DDB</color>
<color name="material_deep_purple_300">#9575CD</color>
<color name="material_deep_purple_400">#7E57C2</color>
<color name="material_deep_purple_500">#673AB7</color>
<color name="material_deep_purple_600">#5E35B1</color>
<color name="material_deep_purple_700">#512DA8</color>
<color name="material_deep_purple_800">#4527A0</color>
<color name="material_deep_purple_900">#311B92</color>
<color name="material_deep_purple_a100">#B388FF</color>
<color name="material_deep_purple_a200">#7C4DFF</color>
<color name="material_deep_purple_a400">#651FFF</color>
<color name="material_deep_purple_a700">#6200EA</color>
<color name="material_indigo_50">#E8EAF6</color>
<color name="material_indigo_100">#C5CAE9</color>
<color name="material_indigo_200">#9FA8DA</color>
<color name="material_indigo_300">#7986CB</color>
<color name="material_indigo_400">#5C6BC0</color>
<color name="material_indigo_500">#3F51B5</color>
<color name="material_indigo_600">#3949AB</color>
<color name="material_indigo_700">#303F9F</color>
<color name="material_indigo_800">#283593</color>
<color name="material_indigo_900">#1A237E</color>
<color name="material_indigo_a100">#8C9EFF</color>
<color name="material_indigo_a200">#536DFE</color>
<color name="material_indigo_a400">#3D5AFE</color>
<color name="material_indigo_a700">#304FFE</color>
<color name="material_blue_50">#E3F2FD</color>
<color name="material_blue_100">#BBDEFB</color>
<color name="material_blue_200">#90CAF9</color>
<color name="material_blue_300">#64B5F6</color>
<color name="material_blue_400">#42A5F5</color>
<color name="material_blue_500">#2196F3</color>
<color name="material_blue_600">#1E88E5</color>
<color name="material_blue_700">#1976D2</color>
<color name="material_blue_800">#1565C0</color>
<color name="material_blue_900">#0D47A1</color>
<color name="material_blue_a100">#82B1FF</color>
<color name="material_blue_a200">#448AFF</color>
<color name="material_blue_a400">#2979FF</color>
<color name="material_blue_a700">#2962FF</color>
<color name="material_light_blue_50">#E1F5FE</color>
<color name="material_light_blue_100">#B3E5FC</color>
<color name="material_light_blue_200">#81D4FA</color>
<color name="material_light_blue_300">#4FC3F7</color>
<color name="material_light_blue_400">#29B6F6</color>
<color name="material_light_blue_500">#03A9F4</color>
<color name="material_light_blue_600">#039BE5</color>
<color name="material_light_blue_700">#0288D1</color>
<color name="material_light_blue_800">#0277BD</color>
<color name="material_light_blue_900">#01579B</color>
<color name="material_light_blue_a100">#80D8FF</color>
<color name="material_light_blue_a200">#40C4FF</color>
<color name="material_light_blue_a400">#00B0FF</color>
<color name="material_light_blue_a700">#0091EA</color>
<color name="material_cyan_50">#E0F7FA</color>
<color name="material_cyan_100">#B2EBF2</color>
<color name="material_cyan_200">#80DEEA</color>
<color name="material_cyan_300">#4DD0E1</color>
<color name="material_cyan_400">#26C6DA</color>
<color name="material_cyan_500">#00BCD4</color>
<color name="material_cyan_600">#00ACC1</color>
<color name="material_cyan_700">#0097A7</color>
<color name="material_cyan_800">#00838F</color>
<color name="material_cyan_900">#006064</color>
<color name="material_cyan_a100">#84FFFF</color>
<color name="material_cyan_a200">#18FFFF</color>
<color name="material_cyan_a400">#00E5FF</color>
<color name="material_cyan_a700">#00B8D4</color>
<color name="material_teal_50">#E0F2F1</color>
<color name="material_teal_100">#B2DFDB</color>
<color name="material_teal_200">#80CBC4</color>
<color name="material_teal_300">#4DB6AC</color>
<color name="material_teal_400">#26A69A</color>
<color name="material_teal_500">#009688</color>
<color name="material_teal_600">#00897B</color>
<color name="material_teal_700">#00796B</color>
<color name="material_teal_800">#00695C</color>
<color name="material_teal_900">#004D40</color>
<color name="material_teal_a100">#A7FFEB</color>
<color name="material_teal_a200">#64FFDA</color>
<color name="material_teal_a400">#1DE9B6</color>
<color name="material_teal_a700">#00BFA5</color>
<color name="material_green_50">#E8F5E9</color>
<color name="material_green_100">#C8E6C9</color>
<color name="material_green_200">#A5D6A7</color>
<color name="material_green_300">#81C784</color>
<color name="material_green_400">#66BB6A</color>
<color name="material_green_500">#4CAF50</color>
<color name="material_green_600">#43A047</color>
<color name="material_green_700">#388E3C</color>
<color name="material_green_800">#2E7D32</color>
<color name="material_green_900">#1B5E20</color>
<color name="material_green_a100">#B9F6CA</color>
<color name="material_green_a200">#69F0AE</color>
<color name="material_green_a400">#00E676</color>
<color name="material_green_a700">#00C853</color>
<color name="material_light_green_50">#F1F8E9</color>
<color name="material_light_green_100">#DCEDC8</color>
<color name="material_light_green_200">#C5E1A5</color>
<color name="material_light_green_300">#AED581</color>
<color name="material_light_green_400">#9CCC65</color>
<color name="material_light_green_500">#8BC34A</color>
<color name="material_light_green_600">#7CB342</color>
<color name="material_light_green_700">#689F38</color>
<color name="material_light_green_800">#558B2F</color>
<color name="material_light_green_900">#33691E</color>
<color name="material_light_green_a100">#CCFF90</color>
<color name="material_light_green_a200">#B2FF59</color>
<color name="material_light_green_a400">#76FF03</color>
<color name="material_light_green_a700">#64DD17</color>
<color name="material_lime_50">#F9FBE7</color>
<color name="material_lime_100">#F0F4C3</color>
<color name="material_lime_200">#E6EE9C</color>
<color name="material_lime_300">#DCE775</color>
<color name="material_lime_400">#D4E157</color>
<color name="material_lime_500">#CDDC39</color>
<color name="material_lime_600">#C0CA33</color>
<color name="material_lime_700">#AFB42B</color>
<color name="material_lime_800">#9E9D24</color>
<color name="material_lime_900">#827717</color>
<color name="material_lime_a100">#F4FF81</color>
<color name="material_lime_a200">#EEFF41</color>
<color name="material_lime_a400">#C6FF00</color>
<color name="material_lime_a700">#AEEA00</color>
<color name="material_yellow_50">#FFFDE7</color>
<color name="material_yellow_100">#FFF9C4</color>
<color name="material_yellow_200">#FFF59D</color>
<color name="material_yellow_300">#FFF176</color>
<color name="material_yellow_400">#FFEE58</color>
<color name="material_yellow_500">#FFEB3B</color>
<color name="material_yellow_600">#FDD835</color>
<color name="material_yellow_700">#FBC02D</color>
<color name="material_yellow_800">#F9A825</color>
<color name="material_yellow_900">#F57F17</color>
<color name="material_yellow_a100">#FFFF8D</color>
<color name="material_yellow_a200">#FFFF00</color>
<color name="material_yellow_a400">#FFEA00</color>
<color name="material_yellow_a700">#FFD600</color>
<color name="material_amber_50">#FFF8E1</color>
<color name="material_amber_100">#FFECB3</color>
<color name="material_amber_200">#FFE082</color>
<color name="material_amber_300">#FFD54F</color>
<color name="material_amber_400">#FFCA28</color>
<color name="material_amber_500">#FFC107</color>
<color name="material_amber_600">#FFB300</color>
<color name="material_amber_700">#FFA000</color>
<color name="material_amber_800">#FF8F00</color>
<color name="material_amber_900">#FF6F00</color>
<color name="material_amber_a100">#FFE57F</color>
<color name="material_amber_a200">#FFD740</color>
<color name="material_amber_a400">#FFC400</color>
<color name="material_amber_a700">#FFAB00</color>
<color name="material_orange_50">#FFF3E0</color>
<color name="material_orange_100">#FFE0B2</color>
<color name="material_orange_200">#FFCC80</color>
<color name="material_orange_300">#FFB74D</color>
<color name="material_orange_400">#FFA726</color>
<color name="material_orange_500">#FF9800</color>
<color name="material_orange_600">#FB8C00</color>
<color name="material_orange_700">#F57C00</color>
<color name="material_orange_800">#EF6C00</color>
<color name="material_orange_900">#E65100</color>
<color name="material_orange_a100">#FFD180</color>
<color name="material_orange_a200">#FFAB40</color>
<color name="material_orange_a400">#FF9100</color>
<color name="material_orange_a700">#FF6D00</color>
<color name="material_deep_orange_50">#FBE9E7</color>
<color name="material_deep_orange_100">#FFCCBC</color>
<color name="material_deep_orange_200">#FFAB91</color>
<color name="material_deep_orange_300">#FF8A65</color>
<color name="material_deep_orange_400">#FF7043</color>
<color name="material_deep_orange_500">#FF5722</color>
<color name="material_deep_orange_600">#F4511E</color>
<color name="material_deep_orange_700">#E64A19</color>
<color name="material_deep_orange_800">#D84315</color>
<color name="material_deep_orange_900">#BF360C</color>
<color name="material_deep_orange_a100">#FF9E80</color>
<color name="material_deep_orange_a200">#FF6E40</color>
<color name="material_deep_orange_a400">#FF3D00</color>
<color name="material_deep_orange_a700">#DD2C00</color>
<color name="material_brown_50">#EFEBE9</color>
<color name="material_brown_100">#D7CCC8</color>
<color name="material_brown_200">#BCAAA4</color>
<color name="material_brown_300">#A1887F</color>
<color name="material_brown_400">#8D6E63</color>
<color name="material_brown_500">#795548</color>
<color name="material_brown_600">#6D4C41</color>
<color name="material_brown_700">#5D4037</color>
<color name="material_brown_800">#4E342E</color>
<color name="material_brown_900">#3E2723</color>
<color name="material_grey_50">#FAFAFA</color>
<color name="material_grey_100">#F5F5F5</color>
<color name="material_grey_200">#EEEEEE</color>
<color name="material_grey_300">#E0E0E0</color>
<color name="material_grey_400">#BDBDBD</color>
<color name="material_grey_500">#9E9E9E</color>
<color name="material_grey_600">#757575</color>
<color name="material_grey_700">#616161</color>
<color name="material_grey_800">#424242</color>
<color name="material_grey_900">#212121</color>
<color name="material_blue_grey_50">#ECEFF1</color>
<color name="material_blue_grey_100">#CFD8DC</color>
<color name="material_blue_grey_200">#B0BEC5</color>
<color name="material_blue_grey_300">#90A4AE</color>
<color name="material_blue_grey_400">#78909C</color>
<color name="material_blue_grey_500">#607D8B</color>
<color name="material_blue_grey_600">#546E7A</color>
<color name="material_blue_grey_700">#455A64</color>
<color name="material_blue_grey_800">#37474F</color>
<color name="material_blue_grey_900">#263238</color>
</resources>

View File

@ -1 +0,0 @@
<resources></resources>

View File

@ -319,4 +319,16 @@
<string name="pref_compat_mode_summary">Compat mode app list</string>
<string name="xposed_not_active">EdXposed Framework is not currently installed or active\nYou can close status check in settings</string>
<string name="transparent_status_bar">Transparent status bar</string>
<string name="list_sort">List sorting</string>
<string name="sort_by_name">Sort by application name</string>
<string name="sort_by_name_reverse">Sort by application name (reverse)</string>
<string name="sort_by_package_name">Sort by package name</string>
<string name="sort_by_package_name_reverse">Sort by package name (reverse)</string>
<string name="sort_by_install_time">Sort by install time</string>
<string name="sort_by_install_time_reverse">Sort by install time (reverse)</string>
<string name="sort_by_update_time">Sort by update time</string>
<string name="sort_by_update_time_reverse">Sort by update time (reverse)</string>
<string name="primary_color">Primary color</string>
<string name="accent_color">Accent color</string>
<string name="colorized_action_bar">Colorized action bar</string>
</resources>

View File

@ -7,14 +7,17 @@
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorActionBar">@color/colorActionBar</item>
<item name="actionBarTheme">@style/ThemeOverlay.MaterialComponents.ActionBar</item>
<item name="android:colorBackground">@color/colorBackground</item>
<item name="android:windowBackground">@color/colorBackground</item>
<item name="actionBarPopupTheme">@style/AppTheme.PopupOverlay</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">@bool/lightSystemUI</item>
<item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">@bool/lightSystemUI
</item>
<item name="android:navigationBarColor">@color/navigationBarColor</item>
<item name="alertDialogTheme">@style/ThemeOverlay.MaterialComponents.MaterialAlertDialog
</item>
<item name="tabLayoutTheme">@style/Widget.MaterialComponents.TabLayout</item>
</style>
<style name="AppearanceFoundation.Caption" parent="TextAppearance.AppCompat.Caption">
@ -26,17 +29,24 @@
<item name="colorPrimaryDark">@color/colorBackground</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Light" />
<style name="ThemeOverlay" />
<style name="ThemeOverlay.ActionBarPrimaryColor">
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorActionBar">@color/colorPrimary</item>
<item name="actionBarTheme">@style/ThemeOverlay.MaterialComponents.Dark.ActionBar</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="tabLayoutTheme">@style/Widget.MaterialComponents.TabLayout.Colored</item>
</style>
<style name="ThemeOverlay.Black">
<item name="colorPrimaryDark">@android:color/black</item>
<item name="colorActionBar">@android:color/black</item>
<item name="android:navigationBarColor">@android:color/black</item>
<item name="android:colorBackground">@android:color/black</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="tabLayoutTheme">@style/Widget.MaterialComponents.TabLayout</item>
</style>
</resources>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,18 @@
android:key="group_app"
android:title="@string/settings_group_app"
app:iconSpaceReserved="false">
<org.meowcat.edxposed.manager.widget.ThemeColorPreference
android:defaultValue="#1976D2"
android:dialogTitle="@string/primary_color"
android:key="primary_color"
android:title="@string/primary_color"
app:iconSpaceReserved="false" />
<org.meowcat.edxposed.manager.widget.ThemeColorPreference
android:defaultValue="#1a73e8"
android:dialogTitle="@string/accent_color"
android:key="accent_color"
android:title="@string/accent_color"
app:iconSpaceReserved="false" />
<org.meowcat.edxposed.manager.widget.IntegerListPreference
android:defaultValue="-1"
android:entries="@array/theme_texts"
@ -14,15 +25,18 @@
android:summary="%s"
android:title="@string/settings_theme"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:key="colorized_action_bar"
android:title="@string/colorized_action_bar"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:key="black_dark_theme"
android:title="@string/pure_black_dark_theme"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
<!--<SwitchPreferenceCompat
android:key="transparent_status_bar"
android:title="@string/transparent_status_bar"
app:iconSpaceReserved="false" />
app:iconSpaceReserved="false" />-->
<SwitchPreferenceCompat
android:defaultValue="true"
@ -44,6 +58,14 @@
android:title="@string/show_modules"
app:iconSpaceReserved="false" />
<org.meowcat.edxposed.manager.widget.IntegerListPreference
android:defaultValue="0"
android:entries="@array/list_sort_texts"
android:entryValues="@array/list_sort_values"
android:key="list_sort"
android:summary="%s"
android:title="@string/list_sort"
app:iconSpaceReserved="false" />
</PreferenceCategory>
<PreferenceCategory