mirror of
https://github.com/TrianguloY/UrlChecker.git
synced 2024-09-19 20:02:16 +02:00
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 <nk865270@dal.ca> Co-authored-by: TrianguloY <correo--correo@hotmail.com>
This commit is contained in:
parent
b9f4fa7c39
commit
f6aec67e7b
@ -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);
|
||||
|
@ -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<String, Boolean> 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())) {
|
||||
try {
|
||||
var ent = jsonPrefs.getJSONObject(key);
|
||||
switch (ent.getString(PREF_TYPE)) {
|
||||
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: " + ent.getString(PREF_TYPE));
|
||||
default -> AndroidUtils.assertError("Unknown type: " + type);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
AndroidUtils.assertError("Error when restoring key: " + key);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.<Spinner>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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 ------------------- */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<AvailableLocale> getLocales(Context cntx) {
|
||||
// check each locale
|
||||
var available = new ArrayList<AvailableLocale>();
|
||||
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 ------------------- */
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
var locale = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
? cntx.getResources().getConfiguration().getLocales().get(0)
|
||||
: cntx.getResources().getConfiguration().locale
|
||||
).format(new Date(millis));
|
||||
: cntx.getResources().getConfiguration().locale;
|
||||
return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale).format(new Date(millis));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<String> 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()
|
||||
);
|
||||
}
|
||||
}
|
@ -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<AvailableLocale> getLocales(Context cntx) {
|
||||
// check each locale
|
||||
var available = new ArrayList<AvailableLocale>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -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<String> 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<String> 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
|
||||
|
Loading…
Reference in New Issue
Block a user