diff --git a/README.md b/README.md
index f2ec466..6540557 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,7 @@
## Fox Module contest
-[NoStorageRestrict](https://github.com/Magisk-Modules-Alt-Repo/NoStorageRestrict)
-by [@DanGLES3](https://github.com/DanGLES3) won via vote in community telegram server.
+[NoStorageRestrict](https://github.com/Magisk-Modules-Alt-Repo/NoStorageRestrict) by [@DanGLES3](https://github.com/DanGLES3) won via vote in community telegram server.
Module description: Removes the restriction when selecting folders (Downloads/Android) through the file manager on Android 11 and higher
@@ -19,12 +18,11 @@ Main activity:
## What is this?
-The official Magisk is dropping support to download online modules...
-So I made my own app to do that! :3
+The official Magisk has dropped support to download online modules, so I made Fox's Magisk Module Manager to help you download and install Magisk modules.
**This app is not officially supported by Magisk or its developers**
-**The modules shown in this app are not affiliated with this app**
+**The modules shown in this app are not affiliated with this app or Magisk**
(Please contact repo owners instead)
## Requirements
diff --git a/app/build.gradle b/app/build.gradle
index aa4c246..94fb2f7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -34,6 +34,7 @@ android {
"default" {
dimension "type"
buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true"
+ buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "true"
buildConfigField(
"java.util.List",
"ENABLED_REPOS",
@@ -50,6 +51,9 @@ android {
// with our keys, so the APK wouldn't install anyways).
buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "false"
+ // Disable crash reporting for F-Droid flavor by default
+ buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "false"
+
// Repo with ads or tracking feature are disabled by default for the
// F-Droid flavor.
buildConfigField(
@@ -79,6 +83,8 @@ configurations {
}
dependencies {
+ // Error reporting
+ implementation 'io.sentry:sentry-android:6.4.0'
// UI
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.emoji2:emoji2:1.2.0'
@@ -87,7 +93,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- implementation 'androidx.webkit:webkit:1.4.0'
+ implementation 'androidx.webkit:webkit:1.5.0'
implementation 'com.google.android.material:material:1.6.1'
implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}"
implementation "dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 70ef911..d55947b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,9 @@
tools:ignore="QueryAllPackagesPermission">
-
+
@@ -16,7 +18,8 @@
-
@@ -24,30 +27,32 @@
-
+
+
+ android:label="@string/title_activity_settings"
+ android:parentActivityName=".MainActivity">
@@ -55,8 +60,8 @@
+ android:label="@string/app_name_short"
+ android:launchMode="singleTask">
@@ -64,10 +69,10 @@
@@ -75,30 +80,45 @@
-
+ android:parentActivityName=".MainActivity"
+ android:theme="@style/Theme.MagiskModuleManager">
-
+
+
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java
index ed9bd2e..8084b52 100644
--- a/app/src/main/java/com/fox2code/mmm/MainActivity.java
+++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java
@@ -37,6 +37,7 @@ import com.google.android.material.progressindicator.LinearProgressIndicator;
import eightbitlab.com.blurview.BlurView;
import eightbitlab.com.blurview.RenderScriptBlur;
+import io.sentry.android.core.SentryAndroid;
public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener,
SearchView.OnQueryTextListener, SearchView.OnCloseListener,
diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java
index 16cf224..9f4b278 100644
--- a/app/src/main/java/com/fox2code/mmm/MainApplication.java
+++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java
@@ -27,6 +27,8 @@ import com.fox2code.mmm.utils.Http;
import com.fox2code.rosettax.LanguageSwitcher;
import com.topjohnwu.superuser.Shell;
+import java.io.IOException;
+import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@@ -42,6 +44,9 @@ import io.noties.markwon.syntax.Prism4jThemeDefault;
import io.noties.markwon.syntax.SyntaxHighlightPlugin;
import io.noties.prism4j.Prism4j;
import io.noties.prism4j.annotations.PrismBundle;
+import io.sentry.JsonObjectWriter;
+import io.sentry.NoOpLogger;
+import io.sentry.android.core.SentryAndroid;
@PrismBundle(
includeAll = true,
@@ -49,6 +54,7 @@ import io.noties.prism4j.annotations.PrismBundle;
)
public class MainApplication extends FoxApplication
implements androidx.work.Configuration.Provider {
+ private static final String TAG = "MainApplication";
private static final String timeFormatString = "dd MMM yyyy"; // Example: 13 july 2001
private static Locale timeFormatLocale =
Resources.getSystem().getConfiguration().locale;
@@ -168,6 +174,11 @@ public class MainApplication extends FoxApplication
getSharedPreferences().edit().putBoolean("has_root_access", bool).apply();
}
+ public static boolean isCrashReportingEnabled() {
+ return getSharedPreferences().getBoolean(
+ "crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING);
+ }
+
public static SharedPreferences getBootSharedPreferences() {
return bootSharedPreferences;
}
@@ -341,6 +352,57 @@ public class MainApplication extends FoxApplication
Log.d("MainApplication", "Emoji compat loaded!");
}, "Emoji compat init.").start();
}
+ SentryAndroid.init(this, options -> {
+ // Note: Sentry library only take a screenshot of Fox Magisk Module Manager.
+ // The screen shot doesn't and cannot contain other applications (if in multi windows)
+ // status bar and notifications (even if notification shade is pulled down)
+
+ // In the possibility you find this library sending anything listed above,
+ // it's a serious bug and a security issue you should report to Google
+ // Google bug bounties on Android are huge, so you can also get rich by doing that.
+ options.setAttachScreenshot(true);
+ // Add a callback that will be used before the event is sent to Sentry.
+ // With this callback, you can modify the event or, when returning null, also discard the event.
+ options.setBeforeSend((event, hint) -> {
+ if (BuildConfig.DEBUG) { // Debug sentry events for debug.
+ StringBuilder stringBuilder = new StringBuilder("Sentry report debug: ");
+ try {
+ event.serialize(new JsonObjectWriter(new Writer() {
+ @Override
+ public void write(char[] cbuf) {
+ stringBuilder.append(cbuf);
+ }
+
+ @Override
+ public void write(char[] chars, int i, int i1) {
+ stringBuilder.append(chars, i, i1);
+ }
+
+ @Override
+ public void write(String str, int off, int len) {
+ stringBuilder.append(str, off, len);
+ }
+
+ @Override
+ public void flush() {}
+
+ @Override
+ public void close() {}
+ }, 4), NoOpLogger.getInstance());
+ } catch (IOException ignored) {}
+ Log.i(TAG, stringBuilder.toString());
+ }
+ // Check saved preferences to see if the user has opted out of crash reporting.
+ // If the user has opted out, return null.
+ if (isCrashReportingEnabled()) {
+ Log.i(TAG, "Relayed sentry report according to user preference");
+ return event;
+ } else {
+ Log.i(TAG, "Blocked sentry report according to user preference");
+ return null;
+ }
+ });
+ });
}
@Override
diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java
index 6f068eb..0806db7 100644
--- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java
+++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java
@@ -21,24 +21,23 @@ import org.json.JSONObject;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import okhttp3.Cookie;
import okhttp3.HttpUrl;
@SuppressWarnings("KotlinInternalInJava")
public final class AndroidacyRepoData extends RepoData {
private static final String TAG = "AndroidacyRepoData";
- private static final HttpUrl OK_HTTP_URL;
+
static {
HttpUrl.Builder OK_HTTP_URL_BUILDER =
new HttpUrl.Builder().scheme("https");
// Using HttpUrl.Builder.host(String) crash the app
OK_HTTP_URL_BUILDER.setHost$okhttp(".androidacy.com");
- OK_HTTP_URL = OK_HTTP_URL_BUILDER.build();
+ OK_HTTP_URL_BUILDER.build();
}
+
// Avoid spamming requests to Androidacy
private long androidacyBlockade = 0;
private String token = null;
@@ -60,30 +59,36 @@ public final class AndroidacyRepoData extends RepoData {
this.defaultSupport = "https://t.me/androidacy_discussions";
this.defaultDonate = "https://www.androidacy.com/membership-join/?utm_source=foxmmm&utm-medium=app&utm_campaign=fox-inapp";
this.defaultSubmitModule = "https://www.androidacy.com/module-repository-applications/";
- this.host = testMode ? "staging-api.androidacy.com" : "api.androidacy.com";
+ this.host = testMode ? "staging-api.androidacy.com" : "production-api.androidacy.com";
this.testMode = testMode;
}
- private static String getCookies() {
- if (Http.hasWebView()) {
- return CookieManager.getInstance().getCookie("https://.androidacy.com/");
- } else {
- Iterator cookies = Http.getCookieJar()
- .loadForRequest(OK_HTTP_URL).iterator();
- if (!cookies.hasNext()) return "";
- StringBuilder stringBuilder = new StringBuilder();
- while (true) {
- stringBuilder.append(cookies.next().toString());
- if (!cookies.hasNext()) return stringBuilder.toString();
- stringBuilder.append(",");
- }
- }
- }
-
public static AndroidacyRepoData getInstance() {
return RepoManager.getINSTANCE().getAndroidacyRepoData();
}
+ public boolean isValidToken(string token) {
+ try {
+ Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, false);
+ } catch (Exception e) {
+ if ("Received error code: 419".equals(e.getMessage()) ||
+ "Received error code: 429".equals(e.getMessage())) {
+ Log.e(TAG, "We are being rate limited!", e);
+ long time = System.currentTimeMillis();
+ this.androidacyBlockade = time + 3_600_000L;
+ return false;
+ }
+ Log.w(TAG, "Invalid token, resetting...");
+ // Remove saved preference
+ SharedPreferences.Editor editor = this.cachedPreferences.edit();
+ editor.remove("androidacy_api_token");
+ editor.apply();
+ return false;
+ }
+ // If status code is 200, we are good
+ return true;
+ }
+
@Override
protected boolean prepare() {
// Implementation details discussed on telegram
@@ -91,57 +96,33 @@ public final class AndroidacyRepoData extends RepoData {
long time = System.currentTimeMillis();
if (this.androidacyBlockade > time) return false;
this.androidacyBlockade = time + 30_000L;
- String cookies = AndroidacyRepoData.getCookies();
- int start = cookies == null ? -1 : cookies.indexOf("USER=") + 5;
- String token = null;
- if (start != -1) {
- int end = cookies.indexOf(";", start);
- if (end != -1)
- token = cookies.substring(start, end);
- }
+ // Get token from androidacy_api_token shared preference
+ String token = this.cachedPreferences.getString("androidacy_api_token", null);
if (token != null) {
- try {
- Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, true);
- } catch (Exception e) {
- if ("Received error code: 419".equals(e.getMessage()) ||
- "Received error code: 429".equals(e.getMessage())) {
- Log.e(TAG, "We are being rate limited!", e);
- this.androidacyBlockade = time + 3_600_000L;
- return false;
- }
- Log.w(TAG, "Invalid token, resetting...");
- if (Http.hasWebView()) {
- CookieManager.getInstance().setCookie("https://.androidacy.com/",
- "USER=; expires=Thu, 01 Jan 1970 00:00:00 GMT;" +
- " path=/; secure; domain=.androidacy.com");
- } else {
- Http.getCookieJar().saveFromResponse(
- OK_HTTP_URL, Collections.emptyList());
- }
- this.token = token = null;
+ this.token = token;
+ if (!isValidToken(token)) {
+ token = null;
}
}
if (token == null) {
try {
Log.i(TAG, "Refreshing token...");
+ // POST request to https://production-api.androidacy.com/auth/register
token = new String(Http.doHttpPost(
"https://" + this.host + "/auth/register",
- "",true), StandardCharsets.UTF_8);
- if (Http.hasWebView()) {
- CookieManager.getInstance().setCookie("https://.androidacy.com/",
- "USER=" + token + "; expires=Fri, 31 Dec 9999 23:59:59 GMT;" +
- " path=/; secure; domain=.androidacy.com");
- } else {
- Http.getCookieJar().saveFromResponse(OK_HTTP_URL,
- Collections.singletonList(Cookie.parse(OK_HTTP_URL,
- "USER=" + token + "; expires=Fri, 31 Dec 9999 23:59:59 GMT;" +
- " path=/; secure; domain=.androidacy.com")));
- }
+ "foxmmm=true", true), StandardCharsets.UTF_8);
+ // Parse token
+ JSONObject jsonObject = new JSONObject(token);
+ token = jsonObject.getString("token");
+ // Save token to shared preference
+ SharedPreferences.Editor editor = this.cachedPreferences.edit();
+ editor.putString("androidacy_api_token", token);
+ editor.apply();
} catch (Exception e) {
if ("Received error code: 419".equals(e.getMessage()) ||
"Received error code: 429".equals(e.getMessage()) ||
"Received error code: 503".equals(e.getMessage())
- ) {
+ ) {
Log.e(TAG, "We are being rate limited!", e);
this.androidacyBlockade = time + 3_600_000L;
}
@@ -194,7 +175,7 @@ public final class AndroidacyRepoData extends RepoData {
jsonObject.optString("zipUrl", ""));
repoModule.notesUrl = filterURL(
jsonObject.optString("notesUrl", ""));
- if (repoModule.zipUrl == null) {
+ if (repoModule.zipUrl == null) {
repoModule.zipUrl = // Fallback url in case the API doesn't have zipUrl
"https://" + this.host + "/magisk/info/" + moduleId;
}
@@ -264,7 +245,8 @@ public final class AndroidacyRepoData extends RepoData {
}
@Override
- public void storeMetadata(RepoModule repoModule, byte[] data) {}
+ public void storeMetadata(RepoModule repoModule, byte[] data) {
+ }
@Override
public boolean tryLoadMetadata(RepoModule repoModule) {
diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java
index 2b4b9dc..4d9baca 100644
--- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java
+++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java
@@ -40,7 +40,7 @@ public final class RepoManager extends SyncManager {
"https://cdn.jsdelivr.net/gh/Magisk-Modules-Alt-Repo/json@main/modules.json";
public static final String ANDROIDACY_MAGISK_REPO_ENDPOINT =
- "https://api.androidacy.com/magisk/repo";
+ "https://production-api.androidacy.com/magisk/repo";
public static final String ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT =
"https://staging-api.androidacy.com/magisk/repo";
public static final String ANDROIDACY_MAGISK_REPO_HOMEPAGE =
diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java
index 3f767f0..4761366 100644
--- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java
+++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java
@@ -8,7 +8,10 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
+import android.view.inputmethod.EditorInfo;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Toast;
@@ -17,10 +20,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SwitchPreferenceCompat;
import androidx.preference.TwoStatePreference;
import com.fox2code.foxcompat.FoxActivity;
@@ -32,6 +38,7 @@ import com.fox2code.mmm.Constants;
import com.fox2code.mmm.MainActivity;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R;
+import com.fox2code.mmm.androidacy.AndroidacyRepoData;
import com.fox2code.mmm.background.BackgroundUpdateChecker;
import com.fox2code.mmm.installer.InstallerInitializer;
import com.fox2code.mmm.module.ActionButtonType;
@@ -45,6 +52,7 @@ import com.fox2code.rosettax.LanguageActivity;
import com.fox2code.rosettax.LanguageSwitcher;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.internal.TextWatcherAdapter;
+import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.mikepenz.aboutlibraries.LibsBuilder;
import com.topjohnwu.superuser.internal.UiThreadHandler;
@@ -70,10 +78,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
setTitle(R.string.app_name);
setActionBarBackground(null);
if (savedInstanceState == null) {
- getSupportFragmentManager()
- .beginTransaction()
- .replace(R.id.settings, new SettingsFragment())
- .commit();
+ getSupportFragmentManager().beginTransaction().replace(R.id.settings, new SettingsFragment()).commit();
}
}
@@ -83,9 +88,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
Intent mStartActivity = new Intent(this, MainActivity.class);
mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int mPendingIntentId = 123456;
- PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId,
- mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- AlarmManager mgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
+ PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0); // Exit app process
}
@@ -96,8 +100,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
super.onPause();
}
- public static class SettingsFragment extends PreferenceFragmentCompat
- implements FoxActivity.OnBackPressedCallback {
+ public static class SettingsFragment extends PreferenceFragmentCompat implements FoxActivity.OnBackPressedCallback {
@Override
@SuppressWarnings("ConstantConditions")
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@@ -119,11 +122,18 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
devModeStep = 0;
UiThreadHandler.handler.postDelayed(() -> {
MainApplication.getINSTANCE().updateTheme();
- FoxActivity.getFoxActivity(this).setThemeRecreate(
- MainApplication.getINSTANCE().getManagerThemeResId());
+ FoxActivity.getFoxActivity(this).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId());
}, 1);
return true;
});
+ // Crash reporting
+ TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting");
+ crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled());
+ crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> {
+ devModeStep = 0;
+ getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", (boolean) newValue).apply();
+ return true;
+ });
Preference enableBlur = findPreference("pref_enable_blur");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
enableBlur.setSummary(R.string.require_android_6);
@@ -138,8 +148,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
disableMonet.setOnPreferenceClickListener(preference -> {
UiThreadHandler.handler.postDelayed(() -> {
MainApplication.getINSTANCE().updateTheme();
- ((FoxActivity) this.requireActivity()).setThemeRecreate(
- MainApplication.getINSTANCE().getManagerThemeResId());
+ ((FoxActivity) this.requireActivity()).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId());
}, 1);
return true;
});
@@ -182,8 +191,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
int level = this.currentLanguageLevel();
if (level != LANGUAGE_SUPPORT_LEVEL) {
- Log.e(TAG, "Detected language level " + level +
- ", latest is " + LANGUAGE_SUPPORT_LEVEL);
+ Log.e(TAG, "Detected language level " + level + ", latest is " + LANGUAGE_SUPPORT_LEVEL);
languageSelector.setSummary(R.string.language_support_outdated);
} else {
if (!"Translated by Fox2Code".equals( // I don't "translate" english
@@ -196,45 +204,45 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
if (!MainApplication.isDeveloper()) {
findPreference("pref_disable_low_quality_module_filter").setVisible(false);
+ // Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app
+ Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false);
+ } else {
+ findPreference("pref_crash").setOnPreferenceClickListener(preference -> {
+ // Hard crash the app
+ throw new RuntimeException("This is a test crash");
+ });
}
- if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND
- || !MainApplication.isDeveloper()) {
+ if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) {
findPreference("pref_use_magisk_install_command").setVisible(false);
}
Preference debugNotification = findPreference("pref_background_update_check_debug");
debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled());
debugNotification.setVisible(MainApplication.isDeveloper());
debugNotification.setOnPreferenceClickListener(preference -> {
- BackgroundUpdateChecker.postNotification(
- this.requireContext(), new Random().nextInt(4) + 2);
+ BackgroundUpdateChecker.postNotification(this.requireContext(), new Random().nextInt(4) + 2);
return true;
});
findPreference("pref_background_update_check").setOnPreferenceChangeListener((preference, newValue) -> {
boolean enabled = Boolean.parseBoolean(String.valueOf(newValue));
debugNotification.setEnabled(enabled);
if (!enabled) {
- BackgroundUpdateChecker.onMainActivityResume(
- this.requireContext());
+ BackgroundUpdateChecker.onMainActivityResume(this.requireContext());
}
return true;
});
- final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false)
- .withLicenseShown(true).withAboutMinimalDesign(false);
+ final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false).withLicenseShown(true).withAboutMinimalDesign(false);
Preference update = findPreference("pref_update");
- update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG ||
- AppUpdateManager.getAppUpdateManager().peekHasUpdate()));
+ update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG || AppUpdateManager.getAppUpdateManager().peekHasUpdate()));
update.setOnPreferenceClickListener(p -> {
devModeStep = 0;
- IntentHelper.openUrl(p.getContext(),
- "https://github.com/Fox2Code/FoxMagiskModuleManager/releases");
+ IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/releases");
return true;
});
if (BuildConfig.DEBUG || BuildConfig.ENABLE_AUTO_UPDATER) {
findPreference("pref_report_bug").setOnPreferenceClickListener(p -> {
devModeStep = 0;
- IntentHelper.openUrl(p.getContext(),
- "https://github.com/Fox2Code/FoxMagiskModuleManager/issues");
+ IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/issues");
return true;
});
} else {
@@ -244,20 +252,17 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
if (devModeStep == 2) {
devModeStep = 0;
if (MainApplication.isDeveloper() && !BuildConfig.DEBUG) {
- MainApplication.getSharedPreferences().edit()
- .putBoolean("developer", false).apply();
+ MainApplication.getSharedPreferences().edit().putBoolean("developer", false).apply();
Toast.makeText(getContext(), // Tell the user something changed
R.string.dev_mode_disabled, Toast.LENGTH_SHORT).show();
} else {
- MainApplication.getSharedPreferences().edit()
- .putBoolean("developer", true).apply();
+ MainApplication.getSharedPreferences().edit().putBoolean("developer", true).apply();
Toast.makeText(getContext(), // Tell the user something changed
R.string.dev_mode_enabled, Toast.LENGTH_SHORT).show();
}
return true;
}
- IntentHelper.openUrl(p.getContext(),
- "https://github.com/Fox2Code/FoxMagiskModuleManager");
+ IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager");
return true;
});
findPreference("pref_support").setOnPreferenceClickListener(p -> {
@@ -271,43 +276,31 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
openFragment(libsBuilder.supportFragment(), R.string.licenses);
return true;
});
- findPreference("pref_pkg_info").setSummary(
- BuildConfig.APPLICATION_ID + " v" +
- BuildConfig.VERSION_NAME + " (" +
- BuildConfig.VERSION_CODE + ")");
+ findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID + " v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")");
+ }
+
+ private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) {
+ return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit();
}
private void openFragment(Fragment fragment, @StringRes int title) {
FoxActivity compatActivity = getFoxActivity(this);
compatActivity.setOnBackPressedCallback(this);
compatActivity.setTitle(title);
- compatActivity.getSupportFragmentManager()
- .beginTransaction()
- .replace(R.id.settings, fragment)
- .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
- .commit();
+ compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
}
@Override
public boolean onBackPressed(FoxActivity compatActivity) {
compatActivity.setTitle(R.string.app_name);
- compatActivity.getSupportFragmentManager()
- .beginTransaction().replace(R.id.settings, this)
- .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
- .commit();
+ compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, this).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
return true;
}
private int currentLanguageLevel() {
- int declaredLanguageLevel =
- this.getResources().getInteger(R.integer.language_support_level);
- if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL)
- return declaredLanguageLevel;
- if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") &&
- this.getResources().getString(R.string.notification_update_pref)
- .equals("Background modules update check") &&
- this.getResources().getString(R.string.notification_update_desc)
- .equals("May increase battery usage")) {
+ int declaredLanguageLevel = this.getResources().getInteger(R.integer.language_support_level);
+ if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) return declaredLanguageLevel;
+ if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") && this.getResources().getString(R.string.notification_update_pref).equals("Background modules update check") && this.getResources().getString(R.string.notification_update_desc).equals("May increase battery usage")) {
return 0;
}
return LANGUAGE_SUPPORT_LEVEL;
@@ -317,6 +310,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
public static class RepoFragment extends PreferenceFragmentCompat {
private static final int CUSTOM_REPO_ENTRIES = 5;
+ @SuppressLint("RestrictedApi")
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
getPreferenceManager().setSharedPreferencesName("mmm");
@@ -326,28 +320,101 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB);
updateCustomRepoList(true);
if (!MainApplication.isDeveloper()) {
- Objects.requireNonNull((Preference) findPreference(
- "pref_androidacy_test_mode")).setVisible(false);
+ Objects.requireNonNull((Preference) findPreference("pref_androidacy_test_mode")).setVisible(false);
+ } else {
+ // Show a warning if user tries to enable test mode
+ Objects.requireNonNull((SwitchPreferenceCompat) findPreference("pref_androidacy_test_mode")).setOnPreferenceChangeListener((preference, newValue) -> {
+ if (Boolean.parseBoolean(String.valueOf(newValue))) {
+ new AlertDialog.Builder(this.requireContext())
+ .setTitle(R.string.warning)
+ .setMessage(R.string.androidacy_test_mode_warning)
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ // Do nothing
+ })
+ .show();
+ }
+ return true;
+ });
}
+ String originalApiKey = MainApplication.getSharedPreferences().getString("pref_androidacy_api_token", "");
+ // Create the pref_androidacy_repo_api_key text input with validation
+ EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key");
+ assert prefAndroidacyRepoApiKey != null;
+ prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> {
+ editText.setSingleLine();
+ // Make the single line wrap
+ editText.setHorizontallyScrolling(false);
+ // Set the height to the height of 2 lines
+ editText.setHeight(editText.getLineHeight() * 3);
+ // Make ok button say "Save"
+ editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
+ });
+ prefAndroidacyRepoApiKey.setPositiveButtonText(R.string.save_api_key);
+ prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> {
+ // Curious if this actually works - so crash the app on purpose
+ // throw new RuntimeException("This is a test crash");
+ // get original api key
+ String apiKey = String.valueOf(newValue);
+ // Show snack bar with indeterminate progress
+ Snackbar.make(requireView(), R.string.checking_api_key, Snackbar.LENGTH_INDEFINITE).setAction(R.string.cancel, v -> {
+ // Restore the original api key
+ prefAndroidacyRepoApiKey.setText(originalApiKey);
+ }).show();
+ // Check the API key on a background thread
+ new Thread(() -> {
+ // If key is empty, just remove it and change the text of the snack bar
+ if (apiKey.isEmpty()) {
+ MainApplication.getSharedPreferences().edit().remove("pref_androidacy_repo_api_key").apply();
+ new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_removed, Snackbar.LENGTH_SHORT).show());
+ } else {
+ // If key < 64 chars, it's not valid
+ if (apiKey.length() < 64) {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show();
+ // Save the original key
+ MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply();
+ // Re-show the dialog with an error
+ prefAndroidacyRepoApiKey.performClick();
+ // Show error
+ prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid));
+ });
+ } else {
+ boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey);
+ // If the key is valid, save it
+ if (valid) {
+ MainApplication.getSharedPreferences().edit().putString("pref_androidacy_repo_api_key", apiKey).apply();
+ new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_valid, Snackbar.LENGTH_SHORT).show());
+ } else {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show();
+ // Save the original key
+ MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply();
+ // Re-show the dialog with an error
+ prefAndroidacyRepoApiKey.performClick();
+ // Show error
+ prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid));
+ });
+ }
+ }
+ }
+ }).start();
+ return true;
+ });
}
@SuppressLint("RestrictedApi")
public void updateCustomRepoList(boolean initial) {
- final SharedPreferences sharedPreferences = Objects.requireNonNull(
- this.getPreferenceManager().getSharedPreferences());
- final CustomRepoManager customRepoManager =
- RepoManager.getINSTANCE().getCustomRepoManager();
+ final SharedPreferences sharedPreferences = Objects.requireNonNull(this.getPreferenceManager().getSharedPreferences());
+ final CustomRepoManager customRepoManager = RepoManager.getINSTANCE().getCustomRepoManager();
for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) {
CustomRepoData repoData = customRepoManager.getRepo(i);
setRepoData(repoData, "pref_custom_repo_" + i);
if (initial) {
- Preference preference =
- findPreference("pref_custom_repo_" + i + "_delete");
+ Preference preference = findPreference("pref_custom_repo_" + i + "_delete");
if (preference == null) continue;
final int index = i;
preference.setOnPreferenceClickListener(preference1 -> {
- sharedPreferences.edit().putBoolean(
- "pref_custom_repo_" + index + "_enabled", false).apply();
+ sharedPreferences.edit().putBoolean("pref_custom_repo_" + index + "_enabled", false).apply();
customRepoManager.removeRepo(index);
updateCustomRepoList(false);
return true;
@@ -356,16 +423,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
}
Preference preference = findPreference("pref_custom_add_repo");
if (preference == null) return;
- preference.setVisible(customRepoManager.canAddRepo() &&
- customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
+ preference.setVisible(customRepoManager.canAddRepo() && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
if (initial) { // Custom repo add button part.
preference = findPreference("pref_custom_add_repo_button");
if (preference == null) return;
preference.setOnPreferenceClickListener(preference1 -> {
final Context context = this.requireContext();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
- final MaterialAutoCompleteTextView input =
- new MaterialAutoCompleteTextView(context);
+ final MaterialAutoCompleteTextView input = new MaterialAutoCompleteTextView(context);
input.setHint(R.string.custom_url);
builder.setIcon(R.drawable.ic_baseline_add_box_24);
builder.setTitle(R.string.add_repo);
@@ -373,28 +438,24 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
builder.setPositiveButton("OK", (dialog, which) -> {
String text = String.valueOf(input.getText());
if (customRepoManager.canAddRepo(text)) {
- final CustomRepoData customRepoData =
- customRepoManager.addRepo(text);
+ final CustomRepoData customRepoData = customRepoManager.addRepo(text);
customRepoData.setEnabled(true);
new Thread("Add Custom Repo Thread") {
@Override
public void run() {
try {
customRepoData.quickPrePopulate();
- } catch (IOException|JSONException e) {
+ } catch (IOException | JSONException e) {
Log.e(TAG, "Failed to preload repo values", e);
}
- UiThreadHandler.handler.post(() -> {
- updateCustomRepoList(false);
- });
+ UiThreadHandler.handler.post(() -> updateCustomRepoList(false));
}
}.start();
}
});
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
AlertDialog alertDialog = builder.show();
- final Button positiveButton =
- alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ final Button positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
input.setValidator(new AutoCompleteTextView.Validator() {
@Override
public boolean isValid(CharSequence charSequence) {
@@ -408,16 +469,12 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
});
input.addTextChangedListener(new TextWatcherAdapter() {
@Override
- public void onTextChanged(
- @NonNull CharSequence charSequence, int i, int i1, int i2) {
- positiveButton.setEnabled(customRepoManager
- .canAddRepo(charSequence.toString()) &&
- customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
+ public void onTextChanged(@NonNull CharSequence charSequence, int i, int i1, int i2) {
+ positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
}
});
positiveButton.setEnabled(false);
- int dp10 = FoxDisplay.dpToPixel(10),
- dp20 = FoxDisplay.dpToPixel(20);
+ int dp10 = FoxDisplay.dpToPixel(10), dp20 = FoxDisplay.dpToPixel(20);
FoxViewCompat.setMargin(input, dp20, dp10, dp20, dp10);
return true;
});
@@ -426,8 +483,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
private void setRepoData(String url) {
final RepoData repoData = RepoManager.getINSTANCE().get(url);
- setRepoData(repoData, "pref_" + (repoData == null ?
- RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId()));
+ setRepoData(repoData, "pref_" + (repoData == null ? RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId()));
}
private void setRepoData(final RepoData repoData, String preferenceName) {
@@ -442,11 +498,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference = findPreference(preferenceName + "_enabled");
if (preference != null) {
((TwoStatePreference) preference).setChecked(repoData.isEnabled());
- preference.setTitle(repoData.isEnabled() ?
- R.string.repo_enabled : R.string.repo_disabled);
+ preference.setTitle(repoData.isEnabled() ? R.string.repo_enabled : R.string.repo_disabled);
preference.setOnPreferenceChangeListener((p, newValue) -> {
- p.setTitle(((Boolean) newValue) ?
- R.string.repo_enabled : R.string.repo_disabled);
+ p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled);
return true;
});
}
@@ -457,8 +511,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference.setVisible(true);
preference.setOnPreferenceClickListener(p -> {
if (homepage.startsWith("https://www.androidacy.com/")) {
- IntentHelper.openUrlAndroidacy(
- getFoxActivity(this), homepage, true);
+ IntentHelper.openUrlAndroidacy(getFoxActivity(this), homepage, true);
} else {
IntentHelper.openUrl(getFoxActivity(this), homepage);
}
@@ -503,8 +556,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
preference.setVisible(true);
preference.setOnPreferenceClickListener(p -> {
if (submissionUrl.startsWith("https://www.androidacy.com/")) {
- IntentHelper.openUrlAndroidacy(
- getFoxActivity(this), submissionUrl, true);
+ IntentHelper.openUrlAndroidacy(getFoxActivity(this), submissionUrl, true);
} else {
IntentHelper.openUrl(getFoxActivity(this), submissionUrl);
}
diff --git a/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml b/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml
new file mode 100644
index 0000000..9cdda53
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 646f642..741e0e2 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -92,4 +92,6 @@
Povolit rozostření
Repozitář povolen
Repozitář zakázán
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 5a0b88a..c0e3ed8 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -94,7 +94,6 @@
Repo hinzufügen
Repo entfernen
Eigene URL
- Das Androidacy-Repo enthält Anzeigen und Tracker.
Backup Modules
Module wiederherstellen
Dieser Vorgang erfordert eine Internetverbindung
@@ -103,4 +102,6 @@
Beschreibung
Deinstallieren
Konfig
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 75b93ef..5c26ca9 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -124,7 +124,6 @@
Προσθήκη αποθετηρίου
Αφαίρεση αποθετηρίου
Προσαρμοσμένη διεύθυνση url
- Το αποθετήριο Androidacy έχει διαφημίσεις και ιχνηλάτες.
Εφεδρικά modules
Επαναφορά module
Αυτή η λειτουργία απαιτεί σύνδεση στο Διαδίκτυο
@@ -144,4 +143,6 @@
Ορισμένες μεταφράσεις για την τρέχουσα γλώσσα δεν είναι ενημερωμένες, παρακαλούμε να συνεισφέρετε στις μεταφράσεις εφαρμογών στο GitHub
Μεταφράστηκε απο Tha_14
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml
index 7de0d58..e8ef531 100644
--- a/app/src/main/res/values-es-rMX/strings.xml
+++ b/app/src/main/res/values-es-rMX/strings.xml
@@ -124,8 +124,9 @@
Añadir Repositorio
Eliminar Repositorio
URL Personalizado
- El repositorio Androidacy tiene anuncios y trackers.
Hacer copia de seguridad de los módulos
Restaurar módulos
Esta operación requiere una conexión a Internet.
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index efce5aa..33720c9 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -87,4 +87,6 @@
Hoidla lubatud
Hoidla keelatud
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 88f5e11..205d017 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -124,8 +124,9 @@
Ajouter dépôt
Supprimer dépôt
URL personnalisée
- Le dépôt Androidacy utilise des publicités et des pisteurs.
Sauvegarder les modules
Restaurer les modules
Cette opération requière une connexion internet
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
index 3815c05..dbef5f2 100644
--- a/app/src/main/res/values-id/strings.xml
+++ b/app/src/main/res/values-id/strings.xml
@@ -93,4 +93,6 @@
Aktifkan blur
Repo diaktifkan
Repo dinonaktifkan
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 367addf..1725d8c 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -127,7 +127,6 @@
Aggiungi Repository
Rimuovi Repository
Url personalizzato
- La repository di Androidacy contiene pubblicità e tracker.
Salva moduli
Ripristina moduli
Questa operazione richiede una connessione ad internet
@@ -149,4 +148,6 @@
Traduzione di tugaia56
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 39f4e9a..78cb62a 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -40,4 +40,6 @@
ソースコード
開発者モードが有効です
Force English language
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 37b3d3e..048de70 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -94,5 +94,6 @@
Tilsløring
Pakkebrønn på
Pakkebrønn av
- Androidacy-pakkebrønnen har reklame og sporere.
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-night-v31/strings.xml b/app/src/main/res/values-night-v31/strings.xml
new file mode 100644
index 0000000..1258a33
--- /dev/null
+++ b/app/src/main/res/values-night-v31/strings.xml
@@ -0,0 +1,5 @@
+
+
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/strings.xml b/app/src/main/res/values-night/strings.xml
new file mode 100644
index 0000000..1258a33
--- /dev/null
+++ b/app/src/main/res/values-night/strings.xml
@@ -0,0 +1,5 @@
+
+
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
+
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 659a1d7..7e9b6fd 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -124,7 +124,6 @@
Dodaj repozytorium
Usuń repozytorium
Niestandardowy URL
- Repo Androidacy korzysta z reklam i trackerów.
Kopia zapasowa modułów
Przywracanie modułów
Ta operacja wymaga połączenia internetowego
@@ -147,4 +146,6 @@
prosimy o rozważenie uzupełnienia tłumaczeń aplikacji na GitHubie.
Tłumaczenie: Daviteusz
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 3e13142..594810b 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -127,7 +127,6 @@
Adicionar Repositório
Remover Repositórios
URL Customizado
- O Repositórios Androidacy possui anuncios e rastreadores.
Fazer backup dos modulos
Restaurar modulos
Essa operação requer uma conexão com a internet
@@ -149,4 +148,6 @@
Algumas traduções para sua lingua atual não esta em dia, por favor considere contribuir para as traduções do app no Github
Traduzido por mi007d e DanGLES3
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 2172cb1..33d5330 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -119,7 +119,6 @@
Adăugare depozit
Eliminare depozit
URL personalizat
- Depozitul Androidacy utilizează reclame și instrumente de urmărire.
Rezervare module
Restabilire module
Această operațiune necesită o conexiune la Internet
@@ -138,4 +137,6 @@
nu sunt actualizate, vă rugăm să luați în considerare contribuția la traducerea aplicației pe GitHub
Tradus de Fox2Code
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 143cc46..560cd61 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -120,8 +120,9 @@
Добавить репо
Убрать репо
Свой URL
- Репо Androidacy содержит рекламу и трекеры.
Резервное копирование модулей
Восстановить модули
Для этого действия потребуется подключение к Интернету
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 70f7e4a..41c29ec 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -92,4 +92,6 @@
Povoliť rozostrenia
Repozitár povolený
Repozitár zakázaný
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 947ec9f..547460b 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -127,7 +127,6 @@
Repo ekle
Repo\'yu kaldır
Özel url
- Androidacy repo\'da reklamlar ve takipçiler vardır.
Modülleri yedekle
Modülleri geri yükle
Bu işlem bir internet bağlantısı gerektirir
@@ -147,4 +146,6 @@
Şimdiki dil için bazı çeviriler güncel değil, lütfen GitHub\'daki uygulama çevirilerine katkıda bulunmayı düşünün
Alprnn357 tarafından çevrildi
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-v23/strings.xml b/app/src/main/res/values-v23/strings.xml
new file mode 100644
index 0000000..1258a33
--- /dev/null
+++ b/app/src/main/res/values-v23/strings.xml
@@ -0,0 +1,5 @@
+
+
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v31/strings.xml b/app/src/main/res/values-v31/strings.xml
new file mode 100644
index 0000000..1258a33
--- /dev/null
+++ b/app/src/main/res/values-v31/strings.xml
@@ -0,0 +1,5 @@
+
+
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
+
\ No newline at end of file
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index c560c0b..dd9348f 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -119,8 +119,9 @@
Thêm kho
Gỡ kho
Url tuỳ chỉnh
- Kho Androidacy có các quảng cáo và trình theo dõi.
Sao lưu mô-đun
Khôi phục mô-đun
Quá trình này yêu cầu kết nối internet
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 936a911..2f66551 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -129,7 +129,6 @@
添加库
移除库
自定义网址
- Androidacy repo具有广告和跟踪器.
备份模块
还原模块
此操作需要互联网连接
@@ -150,4 +149,6 @@
请考虑为 GitHub 上的应用程序翻译做出贡献
由ender-zhao翻译
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 0d080eb..5021afb 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -120,7 +120,6 @@
新增倉庫
移除倉庫
自定義網址
- Androidacy repo 內建廣告和跟蹤器.
備份模組
還原模組
需要網路連線
@@ -140,4 +139,6 @@
如果您使用的當前語言沒有及時更新,請考慮在 GitHub 上的為翻譯做出貢獻。
由 OrStudio.tw(@crcky5322) 提供美妙的翻譯
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index a552495..58a4726 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -24,4 +24,5 @@
#FFFFFFFF
#FFFFFFFF
#FFDADADA
+ #3A3A3A
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2dbccca..b2ba2b6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -129,7 +129,7 @@
Add Repo
Remove Repo
Custom url
- The Androidacy repo has ads and trackers.
+ This repository may display some non-intrusive advertising to cover server and development costs.
Backup modules
Restore modules
This operation require an internet connection
@@ -152,4 +152,20 @@
not up-to-date, please consider contributing to the app translations on GitHub
Translated by Fox2Code
+ Automatically report bugs and performance to the developers
+ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder
+ Androidacy API Key
+ Use a custom API key for Androidacy. Useful for premium subscribers, to remove ads and more.
+ Androidacy API key is empty
+ Current Androidacy API key
+ Could not validate API key. Please check it and try again.
+ API key is valid.
+ Validating API key...
+ Validating API key...
+ Please wait
+ Successfully reset API key
+ Validate
+ Warning!
+ You are setting the app to use a non-production endpoint for Androidacy. This may result in app instability and failure to load the online repo. Do NOT report bugs if you have this switch on. Change will take effect on app restart.
+ Crash the app for testing
diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml
index a0b7c46..8cbb1a8 100644
--- a/app/src/main/res/xml/repo_preferences.xml
+++ b/app/src/main/res/xml/repo_preferences.xml
@@ -1,5 +1,6 @@
-
+
@@ -39,6 +40,27 @@
app:switchTextOn="@string/repo_enabled"
app:switchTextOff="@string/repo_disabled"
app:singleLineTitle="false" />
+
+
+
-
+ app:key="pref_manage_repos"
+ app:singleLineTitle="false"
+ app:title="@string/manage_repos_pref" />
+ app:title="@string/show_incompatible_pref" />
+ app:title="@string/disable_low_quality_module_filter_pref" />
+ app:title="@string/use_magisk_install_command_pref" />
+ app:title="@string/notification_update_pref" />
+ app:singleLineTitle="false"
+ app:title="@string/notification_update_debug_pref" />
+ app:icon="@drawable/ic_baseline_palette_24"
+ app:key="pref_theme"
+ app:singleLineTitle="false"
+ app:title="@string/theme_pref" />
+ app:key="pref_language_selector"
+ app:title="@string/language" />
+ app:key="pref_enable_blur"
+ app:singleLineTitle="false"
+ app:title="@string/enable_blur_pref" />
+ app:key="pref_force_dark_terminal"
+ app:singleLineTitle="false"
+ app:title="@string/force_dark_terminal_title" />
+ app:key="pref_enable_monet"
+ app:singleLineTitle="false"
+ app:title="@string/enable_monet" />
+ app:title="@string/wrap_text_pref" />
+ app:title="@string/dns_over_https_pref" />
+ app:title="@string/showcase_mode_pref" />
+ app:title="@string/prevent_reboot_pref" />
+
+
+
+
-
+
+ app:key="pref_update"
+ app:singleLineTitle="false"
+ app:title="@string/app_update" />
+ app:key="pref_report_bug"
+ app:singleLineTitle="false"
+ app:title="@string/report_bugs" />
+ app:key="pref_source_code"
+ app:singleLineTitle="false"
+ app:title="@string/source_code" />
+ app:key="pref_support"
+ app:singleLineTitle="false"
+ app:title="@string/support" />
+ app:key="pref_show_licenses"
+ app:singleLineTitle="false"
+ app:title="@string/show_licenses" />
+ app:summary="@string/loading" />
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 4ac6860..c4ee15e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
gradlePluginPortal()
}
- project.ext.latestAboutLibsRelease = "10.3.1"
+ project.ext.latestAboutLibsRelease = "10.4.1-a01"
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${latestAboutLibsRelease}"