diff --git a/app/build.gradle b/app/build.gradle index 90dfd129..2d3ad136 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } diff --git a/app/edxpmanager.jks b/app/edxpmanager.jks new file mode 100644 index 00000000..f5028dca Binary files /dev/null and b/app/edxpmanager.jks differ diff --git a/app/src/main/java/org/meowcat/edxposed/manager/AboutActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/AboutActivity.java index 4b5860d7..68f80435 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/AboutActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/AboutActivity.java @@ -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()); } diff --git a/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java index 545734a7..eae2e4ff 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java @@ -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); diff --git a/app/src/main/java/org/meowcat/edxposed/manager/BaseAdvancedInstaller.java b/app/src/main/java/org/meowcat/edxposed/manager/BaseAdvancedInstaller.java index f4e3a92b..825f07f4 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/BaseAdvancedInstaller.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/BaseAdvancedInstaller.java @@ -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(); diff --git a/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java index 566b177b..cb2b4441 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java @@ -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(); diff --git a/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java b/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java index cb8363bd..eeaabfdf 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java @@ -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; diff --git a/app/src/main/java/org/meowcat/edxposed/manager/EdDownloadActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/EdDownloadActivity.java index 9abd0e52..5fe9fd81 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/EdDownloadActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/EdDownloadActivity.java @@ -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 { @Override diff --git a/app/src/main/java/org/meowcat/edxposed/manager/MainActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/MainActivity.java index 2d928113..9b108c7d 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/MainActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/MainActivity.java @@ -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(); diff --git a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java index 9fd39c93..d75ace71 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java @@ -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 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 showList; - Collection fullList = moduleUtil.getModules().values(); + ArrayList showList; + ArrayList 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 { - Collection items; + ArrayList 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 items) { + void addAll(ArrayList items) { this.items = items; notifyDataSetChanged(); } diff --git a/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java index 90e4974e..fab3d22f 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/SettingsActivity.java @@ -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; }); diff --git a/app/src/main/java/org/meowcat/edxposed/manager/StatusInstallerFragment.java b/app/src/main/java/org/meowcat/edxposed/manager/StatusInstallerFragment.java index 899163fa..7ce22345 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/StatusInstallerFragment.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/StatusInstallerFragment.java @@ -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) { diff --git a/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java b/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java index 851aef9f..ff331788 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java @@ -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); } } diff --git a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java index 46f2875e..92c199c1 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppAdapter.java @@ -155,19 +155,16 @@ public class AppAdapter extends RecyclerView.Adapter { 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; } + }); } diff --git a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppHelper.java b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppHelper.java index e500a5f0..e3f542c4 100644 --- a/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppHelper.java +++ b/app/src/main/java/org/meowcat/edxposed/manager/adapters/AppHelper.java @@ -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; diff --git a/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColor.java b/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColor.java new file mode 100644 index 00000000..88f59fb0 --- /dev/null +++ b/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColor.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2019 Hai Zhang + * 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(); +} diff --git a/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColors.java b/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColors.java new file mode 100644 index 00000000..ed2f2090 --- /dev/null +++ b/app/src/main/java/org/meowcat/edxposed/manager/util/CustomThemeColors.java @@ -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; + } + } +} diff --git a/app/src/main/java/org/meowcat/edxposed/manager/widget/ThemeColorPreference.java b/app/src/main/java/org/meowcat/edxposed/manager/widget/ThemeColorPreference.java new file mode 100644 index 00000000..dfceeb99 --- /dev/null +++ b/app/src/main/java/org/meowcat/edxposed/manager/widget/ThemeColorPreference.java @@ -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); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_download_details.xml b/app/src/main/res/layout/activity_download_details.xml index 4295e25d..35476ba7 100644 --- a/app/src/main/res/layout/activity_download_details.xml +++ b/app/src/main/res/layout/activity_download_details.xml @@ -10,18 +10,18 @@ + android:theme="?actionBarTheme"> + app:popupTheme="?actionBarPopupTheme" /> + android:theme="?actionBarTheme"> + app:popupTheme="?actionBarPopupTheme" /> + android:theme="?actionBarTheme"> + app:popupTheme="?actionBarPopupTheme" /> + android:theme="?actionBarTheme"> + app:popupTheme="?actionBarPopupTheme" /> \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index fda56bf9..966097bc 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,14 +1,9 @@ - #2196f3 - #424242 - #448aff + @color/material_blue_700 + #303030 #2E2E2E #383838 - #F44336 - @color/red_500 - #4CAF50 - #FFC107 #B3000000 #EA424242 \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000..e48cb3fc --- /dev/null +++ b/app/src/main/res/values-night/styles.xml @@ -0,0 +1,4 @@ + + + - + diff --git a/app/src/main/res/values/themes_custom.xml b/app/src/main/res/values/themes_custom.xml new file mode 100644 index 00000000..51651003 --- /dev/null +++ b/app/src/main/res/values/themes_custom.xml @@ -0,0 +1,1683 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/themes_custom_colorab.xml b/app/src/main/res/values/themes_custom_colorab.xml new file mode 100644 index 00000000..5a6d43ed --- /dev/null +++ b/app/src/main/res/values/themes_custom_colorab.xml @@ -0,0 +1,1723 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/prefs.xml b/app/src/main/res/xml/prefs.xml index 99937107..42caee6f 100644 --- a/app/src/main/res/xml/prefs.xml +++ b/app/src/main/res/xml/prefs.xml @@ -5,7 +5,18 @@ android:key="group_app" android:title="@string/settings_group_app" app:iconSpaceReserved="false"> - + + + - - + app:iconSpaceReserved="false" />--> +