From f6aec67e7b0c6e2c12f8b81772075ec1798670ca Mon Sep 17 00:00:00 2001 From: Nikul Kukadiya Date: Sat, 25 May 2024 09:12:48 -0300 Subject: [PATCH] Refactor Utils class for Better Readability (#338) Refactored the Utils class to enhance code readability by separating functionalities into two distinct classes: - Created HttpUtils class for HTTP-related operations. - Introduced LocaleUtils class for locale-related operations. - Cleaned up code for improved readability and maintainability. --------- Co-authored-by: Nikulkumar Popatbhai Kukadiya Co-authored-by: TrianguloY --- .../urlchecker/activities/AboutActivity.java | 3 +- .../urlchecker/activities/BackupActivity.java | 27 +++-- .../urlchecker/activities/MainActivity.java | 3 +- .../activities/ModulesActivity.java | 10 +- .../activities/SettingsActivity.java | 8 +- .../activities/TutorialActivity.java | 4 +- .../urlchecker/dialogs/MainDialog.java | 3 +- .../modules/companions/ClearUrlCatalog.java | 5 +- .../urlchecker/modules/companions/Hosts.java | 3 +- .../modules/companions/VersionManager.java | 22 ++-- .../modules/companions/VirusTotalUtility.java | 3 +- .../urlchecker/modules/list/StatusModule.java | 4 +- .../modules/list/UnshortenModule.java | 3 +- .../urlchecker/utilities/AndroidSettings.java | 102 ----------------- .../utilities/methods/AndroidUtils.java | 9 +- .../utilities/methods/HttpUtils.java | 45 ++++++++ .../utilities/methods/LocaleUtils.java | 107 ++++++++++++++++++ .../utilities/methods/StreamUtils.java | 66 +---------- 18 files changed, 222 insertions(+), 205 deletions(-) create mode 100644 app/src/main/java/com/trianguloy/urlchecker/utilities/methods/HttpUtils.java create mode 100644 app/src/main/java/com/trianguloy/urlchecker/utilities/methods/LocaleUtils.java diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/AboutActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/AboutActivity.java index 85f55dc..cf8e349 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/AboutActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/AboutActivity.java @@ -14,6 +14,7 @@ import com.trianguloy.urlchecker.R; import com.trianguloy.urlchecker.utilities.AndroidSettings; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; import com.trianguloy.urlchecker.utilities.methods.Inflater; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import com.trianguloy.urlchecker.utilities.methods.PackageUtils; import java.util.List; @@ -37,7 +38,7 @@ public class AboutActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_about); setTitle(R.string.a_about); AndroidUtils.configureUp(this); diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/BackupActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/BackupActivity.java index 7ea0e67..002ca21 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/BackupActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/BackupActivity.java @@ -32,6 +32,7 @@ import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; import com.trianguloy.urlchecker.utilities.methods.Animations; import com.trianguloy.urlchecker.utilities.methods.JavaUtils; import com.trianguloy.urlchecker.utilities.methods.JavaUtils.Function; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import com.trianguloy.urlchecker.utilities.methods.PackageUtils; import com.trianguloy.urlchecker.utilities.wrappers.ProgressDialog; import com.trianguloy.urlchecker.utilities.wrappers.ZipReader; @@ -69,13 +70,14 @@ public class BackupActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_backup); setTitle(R.string.btn_backupRestore); AndroidUtils.configureUp(this); Animations.enableAnimationsRecursively(this); + // find view UI elements prefs = GenericPref.getPrefs(this); chk_data = findViewById(R.id.chk_data); chk_data_prefs = findViewById(R.id.chk_data_prefs); @@ -272,7 +274,7 @@ public class BackupActivity extends Activity { try (var zip = new ZipReader(uri, this)) { // check version - if (!chk_ignoreNewer.isChecked() && VersionManager.isNewerThanCurrent(zip.getFileString(FILE_VERSION))) { + if (!chk_ignoreNewer.isChecked() && VersionManager.isVersionNewer(zip.getFileString(FILE_VERSION))) { runOnUiThread(() -> Toast.makeText(this, R.string.bck_newer, Toast.LENGTH_LONG).show()); return; } @@ -308,6 +310,7 @@ public class BackupActivity extends Activity { }); } + /** Restore preferences from [fileName] in the [zip] that matches the [predicate]. */ private void restorePreferencesMatching(String fileName, Function predicate, ZipReader zip) throws IOException, JSONException { var preferences = zip.getFileString(fileName); if (preferences == null) return; @@ -324,13 +327,19 @@ public class BackupActivity extends Activity { // add for (var key : JavaUtils.toList(jsonPrefs.keys())) { - var ent = jsonPrefs.getJSONObject(key); - switch (ent.getString(PREF_TYPE)) { - case "String" -> editor.putString(key, ent.getString(PREF_VALUE)); - case "Integer" -> editor.putInt(key, ent.getInt(PREF_VALUE)); - case "Long" -> editor.putLong(key, ent.getLong(PREF_VALUE)); - case "Boolean" -> editor.putBoolean(key, ent.getBoolean(PREF_VALUE)); - default -> AndroidUtils.assertError("Unknown type: " + ent.getString(PREF_TYPE)); + try { + var ent = jsonPrefs.getJSONObject(key); + var type = ent.getString(PREF_TYPE); + switch (type) { + case "String" -> editor.putString(key, ent.getString(PREF_VALUE)); + case "Integer" -> editor.putInt(key, ent.getInt(PREF_VALUE)); + case "Long" -> editor.putLong(key, ent.getLong(PREF_VALUE)); + case "Boolean" -> editor.putBoolean(key, ent.getBoolean(PREF_VALUE)); + default -> AndroidUtils.assertError("Unknown type: " + type); + } + } catch (JSONException e) { + AndroidUtils.assertError("Error when restoring key: " + key); + e.printStackTrace(); } } diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/MainActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/MainActivity.java index 632a83f..b0c484d 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/MainActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/MainActivity.java @@ -14,6 +14,7 @@ import com.trianguloy.urlchecker.fragments.ResultCodeInjector; import com.trianguloy.urlchecker.modules.companions.VersionManager; import com.trianguloy.urlchecker.utilities.AndroidSettings; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import com.trianguloy.urlchecker.utilities.methods.PackageUtils; /** @@ -27,7 +28,7 @@ public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_main); // mark as seen if required diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/ModulesActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/ModulesActivity.java index db4c20c..9324ba6 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/ModulesActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/ModulesActivity.java @@ -21,6 +21,7 @@ import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; import com.trianguloy.urlchecker.utilities.methods.Animations; import com.trianguloy.urlchecker.utilities.methods.Inflater; import com.trianguloy.urlchecker.utilities.methods.JavaUtils; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import java.util.ArrayList; import java.util.Collections; @@ -43,7 +44,7 @@ public class ModulesActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_modules); setTitle(R.string.a_modules); AndroidUtils.configureUp(this); @@ -194,7 +195,8 @@ public class ModulesActivity extends Activity { * Updates the enable status of all the movable buttons */ private void updateMovableButtons() { - for (int i = 0; i < list.getChildCount(); i++) { + var listSize = list.getChildCount(); + for (int i = 0; i < listSize; i++) { View child = list.getChildAt(i); // enable up unless already at the top View up = child.findViewById(R.id.move_up); @@ -202,8 +204,8 @@ public class ModulesActivity extends Activity { up.setAlpha(i > 0 ? 1 : 0.5f); // enable down unless already at the bottom View down = child.findViewById(R.id.move_down); - down.setEnabled(i < list.getChildCount() - 1); - down.setAlpha(i < list.getChildCount() - 1 ? 1 : 0.5f); + down.setEnabled(i < listSize - 1); + down.setAlpha(i < listSize - 1 ? 1 : 0.5f); } } diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/SettingsActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/SettingsActivity.java index a276841..519fd5f 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/SettingsActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/SettingsActivity.java @@ -10,10 +10,12 @@ import android.widget.ArrayAdapter; import android.widget.Spinner; import com.trianguloy.urlchecker.R; +//import com.trianguloy.urlchecker.fragments.BrowserButtonsFragment; import com.trianguloy.urlchecker.fragments.BrowserButtonsFragment; import com.trianguloy.urlchecker.fragments.ResultCodeInjector; import com.trianguloy.urlchecker.utilities.AndroidSettings; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import com.trianguloy.urlchecker.utilities.methods.Animations; import com.trianguloy.urlchecker.utilities.methods.PackageUtils; @@ -28,7 +30,7 @@ public class SettingsActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_settings); setTitle(R.string.a_settings); AndroidUtils.configureUp(this); @@ -86,11 +88,11 @@ public class SettingsActivity extends Activity { */ private void configureLocale() { // init - var pref = AndroidSettings.LOCALE_PREF(this); + var pref = LocaleUtils.LOCALE_PREF(this); var spinner = this.findViewById(R.id.locale); // populate available - var locales = AndroidSettings.getLocales(this); + var locales = LocaleUtils.getLocales(this); var adapter = new ArrayAdapter<>( this, android.R.layout.simple_spinner_item, diff --git a/app/src/main/java/com/trianguloy/urlchecker/activities/TutorialActivity.java b/app/src/main/java/com/trianguloy/urlchecker/activities/TutorialActivity.java index 52e6bfe..2d5e3a6 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/activities/TutorialActivity.java +++ b/app/src/main/java/com/trianguloy/urlchecker/activities/TutorialActivity.java @@ -9,10 +9,12 @@ import android.widget.Button; import android.widget.TextView; import com.trianguloy.urlchecker.R; +//import com.trianguloy.urlchecker.fragments.BrowserButtonsFragment; import com.trianguloy.urlchecker.fragments.BrowserButtonsFragment; import com.trianguloy.urlchecker.fragments.ResultCodeInjector; import com.trianguloy.urlchecker.utilities.AndroidSettings; import com.trianguloy.urlchecker.utilities.generics.GenericPref; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import com.trianguloy.urlchecker.utilities.methods.PackageUtils; import com.trianguloy.urlchecker.utilities.wrappers.DoubleEvent; import com.trianguloy.urlchecker.utilities.wrappers.FixedViewFlipper; @@ -37,7 +39,7 @@ public class TutorialActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, false); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); setContentView(R.layout.activity_tutorial); setTitle(R.string.tutorial); diff --git a/app/src/main/java/com/trianguloy/urlchecker/dialogs/MainDialog.java b/app/src/main/java/com/trianguloy/urlchecker/dialogs/MainDialog.java index 3bb047d..5051751 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/dialogs/MainDialog.java +++ b/app/src/main/java/com/trianguloy/urlchecker/dialogs/MainDialog.java @@ -26,6 +26,7 @@ import com.trianguloy.urlchecker.utilities.AndroidSettings; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; import com.trianguloy.urlchecker.utilities.methods.Animations; import com.trianguloy.urlchecker.utilities.methods.Inflater; +import com.trianguloy.urlchecker.utilities.methods.LocaleUtils; import java.util.ArrayList; import java.util.Collections; @@ -187,7 +188,7 @@ public class MainDialog extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); AndroidSettings.setTheme(this, true); - AndroidSettings.setLocale(this); + LocaleUtils.setLocale(this); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.dialog_main); setFinishOnTouchOutside(true); diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/ClearUrlCatalog.java b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/ClearUrlCatalog.java index e551d6e..2654739 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/ClearUrlCatalog.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/ClearUrlCatalog.java @@ -14,6 +14,7 @@ import com.trianguloy.urlchecker.R; import com.trianguloy.urlchecker.dialogs.JsonEditor; import com.trianguloy.urlchecker.utilities.generics.GenericPref; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; +import com.trianguloy.urlchecker.utilities.methods.HttpUtils; import com.trianguloy.urlchecker.utilities.methods.JavaUtils; import com.trianguloy.urlchecker.utilities.methods.StreamUtils; import com.trianguloy.urlchecker.utilities.wrappers.AssetFile; @@ -284,7 +285,7 @@ public class ClearUrlCatalog { // read content String rawRules; try { - rawRules = StreamUtils.readFromUrl(catalogURL.get()); + rawRules = HttpUtils.readFromUrl(catalogURL.get()); } catch (IOException e) { e.printStackTrace(); return R.string.mClear_urlError; @@ -296,7 +297,7 @@ public class ClearUrlCatalog { // read hash String hash; try { - hash = StreamUtils.readFromUrl(hashURL.get()).trim(); + hash = HttpUtils.readFromUrl(hashURL.get()).trim(); } catch (IOException e) { e.printStackTrace(); return R.string.mClear_hashError; diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/Hosts.java b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/Hosts.java index 7bfe95a..705311c 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/Hosts.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/Hosts.java @@ -7,6 +7,7 @@ import android.util.Pair; import com.trianguloy.urlchecker.R; import com.trianguloy.urlchecker.utilities.generics.JsonCatalog; +import com.trianguloy.urlchecker.utilities.methods.HttpUtils; import com.trianguloy.urlchecker.utilities.methods.JavaUtils; import com.trianguloy.urlchecker.utilities.methods.StreamUtils; import com.trianguloy.urlchecker.utilities.wrappers.InternalFile; @@ -97,7 +98,7 @@ public class Hosts { progress.setMessage(cntx.getString(R.string.mHosts_buildDownload, label, file)); Log.d("HOSTS", "Downloading " + file); - StreamUtils.streamFromUrl(file, line -> { + HttpUtils.streamFromUrl(file, line -> { var parts = line.replaceAll("#.*", "").trim().split(" +"); if (parts.length != 2) return; // valid, add diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VersionManager.java b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VersionManager.java index eb316db..2b29de4 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VersionManager.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VersionManager.java @@ -33,7 +33,7 @@ public class VersionManager { } /** Returns true iff [version] is newer than the current one */ - public static boolean isNewerThanCurrent(String version) { + public static boolean isVersionNewer(String version) { // shortcut to check own version if (BuildConfig.VERSION_NAME.equals(version)) return false; @@ -42,18 +42,20 @@ public class VersionManager { if (versionSplit.isEmpty()) return true; // compare: "1" < "2", "1" < "1.1" var currentSplit = split(BuildConfig.VERSION_NAME); - var i = 0; - while (true) { - // end of version, version is older (or equal) - if (versionSplit.size() <= i) return false; - // end of current, version is newer - if (currentSplit.size() <= i) return true; + + for (var i = 0; i < Math.min(versionSplit.size(), currentSplit.size()); i++) { + var versionPart = versionSplit.get(i); + var currentPart = currentSplit.get(i); + // version is older - if (versionSplit.get(i) < currentSplit.get(i)) return false; + if (versionPart < currentPart) return false; // version is newer - if (versionSplit.get(i) > currentSplit.get(i)) return true; - i++; + if (versionPart > currentPart) return true; } + + // If all parts are equal up to the minimum length, the version with more parts is newer + // (and if both are equal, then it is not newer) + return versionSplit.size() > currentSplit.size(); } /* ------------------- instance ------------------- */ diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VirusTotalUtility.java b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VirusTotalUtility.java index bdca5ef..84c3b8f 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VirusTotalUtility.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/companions/VirusTotalUtility.java @@ -3,6 +3,7 @@ package com.trianguloy.urlchecker.modules.companions; import android.content.Context; import com.trianguloy.urlchecker.R; +import com.trianguloy.urlchecker.utilities.methods.HttpUtils; import com.trianguloy.urlchecker.utilities.methods.StreamUtils; import org.json.JSONException; @@ -34,7 +35,7 @@ public class VirusTotalUtility { String responseJSON; try { - responseJSON = StreamUtils.performPOST(urlGetReport, getPOSTparameters(urlToScan, key)); + responseJSON = HttpUtils.performPOST(urlGetReport, getPOSTparameters(urlToScan, key)); } catch (IOException e) { e.printStackTrace(); result.error = cntx.getString(R.string.mVT_connectError); diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/list/StatusModule.java b/app/src/main/java/com/trianguloy/urlchecker/modules/list/StatusModule.java index 46ccf7f..5b64493 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/list/StatusModule.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/list/StatusModule.java @@ -17,7 +17,7 @@ import com.trianguloy.urlchecker.modules.AModuleDialog; import com.trianguloy.urlchecker.url.UrlData; import com.trianguloy.urlchecker.utilities.generics.GenericPref; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; -import com.trianguloy.urlchecker.utilities.methods.StreamUtils; +import com.trianguloy.urlchecker.utilities.methods.HttpUtils; import java.io.IOException; import java.net.HttpURLConnection; @@ -183,7 +183,7 @@ class StatusDialog extends AModuleDialog { // perform GET to the url conn = (HttpURLConnection) new URL(url).openConnection(); conn.setInstanceFollowRedirects(false); // Make the logic below easier to detect redirections - conn.setConnectTimeout(StreamUtils.CONNECT_TIMEOUT); + conn.setConnectTimeout(HttpUtils.CONNECT_TIMEOUT); var responseCode = conn.getResponseCode(); Log.d("RESPONSE_CODE", url + ": " + responseCode); diff --git a/app/src/main/java/com/trianguloy/urlchecker/modules/list/UnshortenModule.java b/app/src/main/java/com/trianguloy/urlchecker/modules/list/UnshortenModule.java index 6048252..84995a1 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/modules/list/UnshortenModule.java +++ b/app/src/main/java/com/trianguloy/urlchecker/modules/list/UnshortenModule.java @@ -14,6 +14,7 @@ import com.trianguloy.urlchecker.modules.AModuleDialog; import com.trianguloy.urlchecker.modules.DescriptionConfig; import com.trianguloy.urlchecker.url.UrlData; import com.trianguloy.urlchecker.utilities.methods.AndroidUtils; +import com.trianguloy.urlchecker.utilities.methods.HttpUtils; import com.trianguloy.urlchecker.utilities.methods.StreamUtils; import org.json.JSONException; @@ -108,7 +109,7 @@ class UnshortenDialog extends AModuleDialog { try { // get response - var response = new JSONObject(StreamUtils.readFromUrl("https://unshorten.me/json/" + getUrl())); + var response = new JSONObject(HttpUtils.readFromUrl("https://unshorten.me/json/" + getUrl())); var resolved_url = response.getString("resolved_url"); var usage_count = Integer.parseInt(response.optString("usage_count", "0")); var ref = new Object() { // reference object to allow using these inside lambdas diff --git a/app/src/main/java/com/trianguloy/urlchecker/utilities/AndroidSettings.java b/app/src/main/java/com/trianguloy/urlchecker/utilities/AndroidSettings.java index 53a7032..2174fb1 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/utilities/AndroidSettings.java +++ b/app/src/main/java/com/trianguloy/urlchecker/utilities/AndroidSettings.java @@ -18,108 +18,6 @@ import java.util.Locale; public interface AndroidSettings { - /* ------------------- locale ------------------- */ - - /** - * The locale pref - */ - static GenericPref.Str LOCALE_PREF(Context cntx) { - return new GenericPref.Str("locale", "", cntx); - } - - /** - * Sets the locale to an activity - */ - static void setLocale(Activity cntx) { - cntx.getResources().updateConfiguration( - getConfig(parseLocale(LOCALE_PREF(cntx).get())), - cntx.getResources().getDisplayMetrics() - ); - } - - /** - * Container for a locale with a given name - */ - class AvailableLocale { - public final String tag; - public final Locale locale; - public final String name; - - public AvailableLocale(String tag, Locale locale, String name) { - this.tag = tag; - this.locale = locale; - this.name = name; - } - - public AvailableLocale(String name) { - this.tag = ""; - this.locale = null; - this.name = name; - } - - @Override - public String toString() { - return name + (tag.isEmpty() ? "" : " (" + tag + ")"); - } - } - - /** - * Returns the list of available/installed locales (plus a 'default' at the top) - */ - static List getLocales(Context cntx) { - // check each locale - var available = new ArrayList(); - for (var tag : BuildConfig.LOCALES) { - var locale = parseLocale(tag); - - // check if available on this device (with split apks the device may not have the translation downloaded) - var localeName = getStringForLocale(R.string.locale, locale, cntx); - if (available.isEmpty() || !available.get(0).name.equals(localeName)) { - // either english (first one) or a translation exists - // note that translations may not exists because PlayStore only installs locales configured by the user - available.add(new AvailableLocale(tag, locale, localeName)); - } else { - if (BuildConfig.DEBUG) Log.d("LOCALE", "Locale " + tag + " is not present"); - } - } - Collections.sort(available, (a, b) -> a.toString().compareTo(b.toString())); - available.add(0, new AvailableLocale(cntx.getString(R.string.deviceDefault))); - return available; - } - - /** - * returns a specific string in a specific locale - */ - static String getStringForLocale(int id, Locale locale, Context cntx) { - return cntx.createConfigurationContext(getConfig(locale)).getString(id); - } - - /** - * returns a configuration object for the given locale - */ - static Configuration getConfig(Locale locale) { - Configuration config = new Configuration(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - config.setLocale(locale); - } else { - config.locale = locale; - } - return config; - } - - /** - * returns a locale for the given tag (language[-country[-variant]]) - */ - static Locale parseLocale(String locale) { - if (locale.isEmpty()) return null; - try { - var parts = locale.split("-"); - return new Locale(parts[0], parts.length > 1 ? parts[1] : "", parts.length > 2 ? parts[2] : ""); - } catch (Exception e) { - return null; - } - } - /* ------------------- day/light theme ------------------- */ /** diff --git a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/AndroidUtils.java b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/AndroidUtils.java index 2afefa2..45d35c9 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/AndroidUtils.java +++ b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/AndroidUtils.java @@ -99,11 +99,10 @@ public interface AndroidUtils { static String formatMillis(long millis, Context cntx) { if (millis < 0) return "---"; - return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.N - ? cntx.getResources().getConfiguration().getLocales().get(0) - : cntx.getResources().getConfiguration().locale - ).format(new Date(millis)); + var locale = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N + ? cntx.getResources().getConfiguration().getLocales().get(0) + : cntx.getResources().getConfiguration().locale; + return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale).format(new Date(millis)); } /** diff --git a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/HttpUtils.java b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/HttpUtils.java new file mode 100644 index 0000000..cd9abe5 --- /dev/null +++ b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/HttpUtils.java @@ -0,0 +1,45 @@ +package com.trianguloy.urlchecker.utilities.methods; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + + +/** HttpUtils class contains the method related to url. */ +public class HttpUtils { + public static final int CONNECT_TIMEOUT = 5000; + + /** GETs an URL and returns the content as a string. */ + public static String readFromUrl(String url) throws IOException { + var connection = new URL(url).openConnection(); + connection.setConnectTimeout(CONNECT_TIMEOUT); + return StreamUtils.inputStream2String(connection.getInputStream()); + } + + /** GETs an URL and streams its lines. */ + public static void streamFromUrl(String url, JavaUtils.Consumer consumer) throws IOException { + var connection = new URL(url).openConnection(); + connection.setConnectTimeout(CONNECT_TIMEOUT); + StreamUtils.consumeLines(connection.getInputStream(), consumer); + } + + /** POSTs something (a body) to an URL and returns its content as a string. */ + public static String performPOST(String url, String body) throws IOException { + // Send POST data request + var conn = (HttpsURLConnection) new URL(url).openConnection(); + conn.setDoOutput(true); + conn.setConnectTimeout(CONNECT_TIMEOUT); + try (var wr = new OutputStreamWriter(conn.getOutputStream())) { + wr.write(body); + wr.flush(); + } + // Get the server response + return StreamUtils.inputStream2String( + conn.getResponseCode() >= 200 && conn.getResponseCode() < 300 + ? conn.getInputStream() + : conn.getErrorStream() + ); + } +} diff --git a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/LocaleUtils.java b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/LocaleUtils.java new file mode 100644 index 0000000..257fb08 --- /dev/null +++ b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/LocaleUtils.java @@ -0,0 +1,107 @@ +package com.trianguloy.urlchecker.utilities.methods; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.Log; + +import com.trianguloy.urlchecker.BuildConfig; +import com.trianguloy.urlchecker.R; +import com.trianguloy.urlchecker.utilities.generics.GenericPref; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +/** Utilities related to translations */ +public interface LocaleUtils { + + /** Returns a locale for the given tag (language[-country[-variant]]) */ + static Locale parseLocale(String locale) { + if (locale.isEmpty()) return null; + try { + var parts = locale.split("-"); + return new Locale(parts[0], parts.length > 1 ? parts[1] : "", parts.length > 2 ? parts[2] : ""); + } catch (Exception e) { + return null; + } + } + + /** Returns a configuration object for the given locale */ + static Configuration getConfig(Locale locale) { + var config = new Configuration(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + config.setLocale(locale); + } else { + config.locale = locale; + } + return config; + } + + /** The locale pref */ + static GenericPref.Str LOCALE_PREF(Context cntx) { + return new GenericPref.Str("locale", "", cntx); + } + + /** Sets the locale to an activity */ + static void setLocale(Activity cntx) { + cntx.getResources().updateConfiguration( + getConfig(parseLocale(LOCALE_PREF(cntx).get())), + cntx.getResources().getDisplayMetrics() + ); + } + + /** Container for a locale with a given name */ + class AvailableLocale { + public final String tag; + public final Locale locale; + public final String name; + + public AvailableLocale(String tag, Locale locale, String name) { + this.tag = tag; + this.locale = locale; + this.name = name; + } + + public AvailableLocale(String name) { + this.tag = ""; + this.locale = null; + this.name = name; + } + + @Override + public String toString() { + return name + (tag.isEmpty() ? "" : " (" + tag + ")"); + } + } + + /** Returns the list of available/installed locales (plus a 'default' at the top) */ + static List getLocales(Context cntx) { + // check each locale + var available = new ArrayList(); + for (var tag : BuildConfig.LOCALES) { + var locale = parseLocale(tag); + + // check if available on this device (with split apks the device may not have the translation downloaded) + var localeName = getStringForLocale(R.string.locale, locale, cntx); + if (available.isEmpty() || !available.get(0).name.equals(localeName)) { + // either english (first one) or a translation exists + // note that translations may not exists because PlayStore only installs locales configured by the user + available.add(new AvailableLocale(tag, locale, localeName)); + } else { + if (BuildConfig.DEBUG) Log.d("LOCALE", "Locale " + tag + " is not present"); + } + } + Collections.sort(available, (a, b) -> a.toString().compareTo(b.toString())); + available.add(0, new AvailableLocale(cntx.getString(R.string.deviceDefault))); + return available; + } + + /** returns a specific string in a specific locale */ + static String getStringForLocale(int id, Locale locale, Context cntx) { + return cntx.createConfigurationContext(getConfig(locale)).getString(id); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/StreamUtils.java b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/StreamUtils.java index 99266c0..edc609f 100644 --- a/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/StreamUtils.java +++ b/app/src/main/java/com/trianguloy/urlchecker/utilities/methods/StreamUtils.java @@ -7,69 +7,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.net.URL; -import java.net.URLConnection; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import javax.net.ssl.HttpsURLConnection; - /** * Generic utilities related to streams (urls, strings, bytes...) */ public interface StreamUtils { Charset UTF_8 = Charset.forName("UTF-8"); // StandardCharsets.UTF_8 requires api 19 - int CONNECT_TIMEOUT = 5000; - /** - * GETs an url and returns the content as string - */ - static String readFromUrl(String url) throws IOException { - URLConnection connection = new URL(url).openConnection(); - connection.setConnectTimeout(CONNECT_TIMEOUT); - return inputStream2String(connection.getInputStream()); - } - - /** - * GETs an url and streams their lines - */ - static void streamFromUrl(String url, JavaUtils.Consumer consumer) throws IOException { - URLConnection connection = new URL(url).openConnection(); - connection.setConnectTimeout(CONNECT_TIMEOUT); - consumeLines(connection.getInputStream(), consumer); - } - - /** - * POSTs something (a body) to an url, returns its content as a string - */ - static String performPOST(String url, String body) throws IOException { - - // Defined URL where to send data - URL urlObject = new URL(url); - - // Send POST data request - HttpsURLConnection conn = (HttpsURLConnection) urlObject.openConnection(); - conn.setDoOutput(true); - conn.setConnectTimeout(CONNECT_TIMEOUT); - OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); - wr.write(body); - wr.flush(); - - // Get the server response - return inputStream2String( - conn.getResponseCode() >= 200 && conn.getResponseCode() < 300 - ? conn.getInputStream() - : conn.getErrorStream() - ); - - } - - /** - * Reads an input stream and returns its content as string. - * The stream is closed afterwards - */ + /** Reads an input stream and returns its content as a string. The stream is closed afterwards. */ static String inputStream2String(InputStream is) throws IOException { try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, UTF_8))) { StringBuilder sb = new StringBuilder(); @@ -82,14 +30,14 @@ public interface StreamUtils { } } - /** Reads an inputStream and transfers its content to a file. The stream is NOT closed */ + /** Reads an input stream and transfers its content to a file. The stream is NOT closed. */ static void inputStream2File(InputStream in, File file) throws IOException { try (var out = new FileOutputStream(file)) { inputStream2OutputStream(in, out); } } - /** Reads an inputStream and transfers its content to an output stream. The streams are NOT closed */ + /** Reads an input stream and transfers its content to an output stream. The streams are NOT closed. */ static void inputStream2OutputStream(InputStream in, OutputStream out) throws IOException { var buffer = new byte[10240]; int read; @@ -98,9 +46,7 @@ public interface StreamUtils { } } - /** - * Reads an input stream and streams its lines - */ + /** Reads an input stream and streams its lines. */ static void consumeLines(InputStream is, JavaUtils.Consumer function) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, UTF_8))) { String line; @@ -112,9 +58,7 @@ public interface StreamUtils { } } - /** - * Returns the sha-256 of a string - */ + /** Returns the SHA-256 hash of a string. */ static String sha256(String string) { try { // get byte array