dandelion/app/src/main/java/io/github/gsantner/opoc/util/Helpers.java

317 lines
12 KiB
Java
Raw Normal View History

2017-05-29 19:05:37 +02:00
/*
* ---------------------------------------------------------------------------- *
* Gregor Santner <gsantner.github.io> wrote this file. You can do whatever
* you want with this stuff. If we meet some day, and you think this stuff is
* worth it, you can buy me a coke in return. Provided as is without any kind
* of warranty. No attribution required. - Gregor Santner
*
2017-07-29 04:44:28 +02:00
* License of this file: Creative Commons Zero (CC0 1.0)
2017-05-29 19:05:37 +02:00
* http://creativecommons.org/publicdomain/zero/1.0/
* ----------------------------------------------------------------------------
*/
package io.github.gsantner.opoc.util;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Color;
2017-05-29 19:05:37 +02:00
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.RawRes;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatButton;
2017-07-29 04:44:28 +02:00
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
2017-05-29 19:05:37 +02:00
import android.text.TextUtils;
2017-07-29 04:44:28 +02:00
import android.text.method.LinkMovementMethod;
2017-05-29 19:05:37 +02:00
import android.util.DisplayMetrics;
import android.webkit.WebView;
2017-07-29 04:44:28 +02:00
import android.widget.TextView;
2017-05-29 19:05:37 +02:00
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
2017-08-09 17:23:19 +02:00
import java.lang.reflect.Field;
2017-05-29 19:05:37 +02:00
import java.util.Locale;
2017-08-09 17:23:19 +02:00
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection"})
2017-05-29 19:05:37 +02:00
public class Helpers {
2017-08-09 17:23:19 +02:00
//########################
//## Members, Constructors
//########################
protected Context _context;
2017-05-29 19:05:37 +02:00
2017-08-09 17:23:19 +02:00
public Helpers(Context context) {
_context = context;
2017-05-29 19:05:37 +02:00
}
2017-08-09 17:23:19 +02:00
//########################
//## Methods
//########################
public String str(@StringRes int strResId) {
return _context.getString(strResId);
2017-05-29 19:05:37 +02:00
}
2017-08-09 17:23:19 +02:00
static class ResType {
public static final String DRAWABLE = "drawable";
public static final String STRING = "string";
public static final String PLURAL = "plural";
public static final String COLOR = "color";
public static final String STYLE = "style";
public static final String ARRAY = "array";
public static final String DIMEN = "dimen";
public static final String MENU = "menu";
public static final String RAW = "raw";
2017-05-29 19:05:37 +02:00
}
public Drawable drawable(@DrawableRes int resId) {
2017-08-09 17:23:19 +02:00
return ContextCompat.getDrawable(_context, resId);
2017-05-29 19:05:37 +02:00
}
public int color(@ColorRes int resId) {
2017-08-09 17:23:19 +02:00
return ContextCompat.getColor(_context, resId);
2017-05-29 19:05:37 +02:00
}
public Context context() {
2017-08-09 17:23:19 +02:00
return _context;
2017-05-29 19:05:37 +02:00
}
public String colorToHexString(int intColor) {
return String.format("#%06X", 0xFFFFFF & intColor);
}
public String getAppVersionName() {
try {
2017-08-09 17:23:19 +02:00
PackageManager manager = _context.getPackageManager();
PackageInfo info = manager.getPackageInfo(_context.getPackageName(), 0);
2017-05-29 19:05:37 +02:00
return info.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
2017-08-09 17:23:19 +02:00
return "?";
2017-05-29 19:05:37 +02:00
}
}
2017-08-09 17:23:19 +02:00
public int getResId(final String type, final String name) {
return _context.getResources().getIdentifier(name, type, _context.getPackageName());
}
2017-05-29 19:05:37 +02:00
2017-08-09 17:23:19 +02:00
public boolean areResIdsAvailable(final String type, final String... names) {
for (String name : names) {
if (getResId(type, name) == 0) {
return false;
}
}
return true;
}
public void openWebpageInExternalBrowser(final String url) {
2017-05-29 19:05:37 +02:00
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2017-08-09 17:23:19 +02:00
_context.startActivity(intent);
}
/**
* https://stackoverflow.com/a/25267049
* Gets a field from the project's BuildConfig. This is useful when, for example, flavors
* are used at the project level to set custom fields.
*
* @param fieldName The name of the field-to-access
* @return The value of the field, or {@code null} if the field is not found.
*/
public Object getBuildConfigValue(String fieldName) {
try {
Class<?> clazz = Class.forName(_context.getPackageName() + ".BuildConfig");
Field field = clazz.getField(fieldName);
return field.get(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public boolean getBuildConfigBoolean(String fieldName, boolean defaultValue) {
Object field = getBuildConfigValue(fieldName);
if (field != null && field instanceof Boolean) {
return (Boolean) field;
}
return defaultValue;
}
public boolean isGooglePlayBuild() {
return getBuildConfigBoolean("IS_GPLAY_BUILD", true);
2017-05-29 19:05:37 +02:00
}
2017-08-09 17:23:19 +02:00
public boolean isFossBuild() {
return getBuildConfigBoolean("IS_FOSS_BUILD", false);
}
// Requires donate__bitcoin_* resources (see below) to be available as string resource
public void showDonateBitcoinRequest(@StringRes final int strResBitcoinId, @StringRes final int strResBitcoinAmount, @StringRes final int strResBitcoinMessage, @StringRes final int strResAlternativeDonateUrl) {
if (!isGooglePlayBuild()) {
2017-05-29 19:05:37 +02:00
String btcUri = String.format("bitcoin:%s?amount=%s&label=%s&message=%s",
2017-08-09 17:23:19 +02:00
str(strResBitcoinId), str(strResBitcoinAmount),
str(strResBitcoinMessage), str(strResBitcoinMessage));
2017-05-29 19:05:37 +02:00
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(btcUri));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
2017-08-09 17:23:19 +02:00
_context.startActivity(intent);
2017-05-29 19:05:37 +02:00
} catch (ActivityNotFoundException e) {
2017-08-09 17:23:19 +02:00
openWebpageInExternalBrowser(str(strResAlternativeDonateUrl));
2017-05-29 19:05:37 +02:00
}
}
}
public String readTextfileFromRawRes(@RawRes int rawResId, String linePrefix, String linePostfix) {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
String line;
linePrefix = linePrefix == null ? "" : linePrefix;
linePostfix = linePostfix == null ? "" : linePostfix;
try {
2017-08-09 17:23:19 +02:00
br = new BufferedReader(new InputStreamReader(_context.getResources().openRawResource(rawResId)));
2017-05-29 19:05:37 +02:00
while ((line = br.readLine()) != null) {
sb.append(linePrefix);
sb.append(line);
sb.append(linePostfix);
sb.append("\n");
}
} catch (Exception ignored) {
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
return sb.toString();
}
public void showDialogWithRawFileInWebView(String fileInRaw, @StringRes int resTitleId) {
2017-08-09 17:23:19 +02:00
WebView wv = new WebView(_context);
2017-05-29 19:05:37 +02:00
wv.loadUrl("file:///android_res/raw/" + fileInRaw);
2017-08-09 17:23:19 +02:00
AlertDialog.Builder dialog = new AlertDialog.Builder(_context)
2017-05-29 19:05:37 +02:00
.setPositiveButton(android.R.string.ok, null)
.setTitle(resTitleId)
.setView(wv);
dialog.show();
}
@SuppressLint("RestrictedApi")
public void setTintColorOfButton(AppCompatButton button, @ColorRes int resColor) {
button.setSupportBackgroundTintList(ColorStateList.valueOf(
color(resColor)
));
}
public boolean isConnectedToInternet() {
ConnectivityManager connectivityManager = (ConnectivityManager)
2017-08-09 17:23:19 +02:00
_context.getSystemService(Context.CONNECTIVITY_SERVICE);
2017-05-29 19:05:37 +02:00
NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
return activeNetInfo != null && activeNetInfo.isConnectedOrConnecting();
}
public void restartApp(Class classToStartupWith) {
2017-08-09 17:23:19 +02:00
Intent restartIntent = new Intent(_context, classToStartupWith);
PendingIntent restartIntentP = PendingIntent.getActivity(_context, 555,
2017-05-29 19:05:37 +02:00
restartIntent, PendingIntent.FLAG_CANCEL_CURRENT);
2017-08-09 17:23:19 +02:00
AlarmManager mgr = (AlarmManager) _context.getSystemService(Context.ALARM_SERVICE);
2017-05-29 19:05:37 +02:00
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, restartIntentP);
System.exit(0);
}
public String loadMarkdownForTextViewFromRaw(@RawRes int rawMdFile, String prepend) {
try {
return new SimpleMarkdownParser()
2017-08-09 17:23:19 +02:00
.parse(_context.getResources().openRawResource(rawMdFile),
2017-07-29 04:44:28 +02:00
prepend, SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW)
2017-08-09 17:23:19 +02:00
.replaceColor("#000001", color(getResId(ResType.COLOR, "accent")))
2017-05-29 19:05:37 +02:00
.removeMultiNewlines().replaceBulletCharacter("*").getHtml();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
2017-07-29 04:44:28 +02:00
public void setHtmlToTextView(TextView textView, String html) {
Spanned spanned;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
spanned = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
} else {
spanned = Html.fromHtml(html);
}
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(new SpannableString(spanned));
}
2017-05-29 19:05:37 +02:00
public double getEstimatedScreenSizeInches() {
2017-08-09 17:23:19 +02:00
DisplayMetrics dm = _context.getResources().getDisplayMetrics();
2017-05-29 19:05:37 +02:00
double density = dm.density * 160;
double x = Math.pow(dm.widthPixels / density, 2);
double y = Math.pow(dm.heightPixels / density, 2);
double screenInches = Math.sqrt(x + y) * 1.16; // 1.16 = est. Nav/Statusbar
screenInches = screenInches < 4.0 ? 4.0 : screenInches;
screenInches = screenInches > 12.0 ? 12.0 : screenInches;
return screenInches;
}
public boolean isInPortraitMode() {
2017-08-09 17:23:19 +02:00
return _context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
2017-05-29 19:05:37 +02:00
}
public Locale getLocaleByAndroidCode(String code) {
if (!TextUtils.isEmpty(code)) {
return code.contains("-r")
? new Locale(code.substring(0, 2), code.substring(4, 6)) // de-rAt
: new Locale(code); // de
}
return Locale.getDefault();
}
// "en"/"de"/"de-rAt"; Empty string = default locale
public void setAppLanguage(String androidLocaleString) {
Locale locale = getLocaleByAndroidCode(androidLocaleString);
2017-08-09 17:23:19 +02:00
Configuration config = _context.getResources().getConfiguration();
2017-05-29 19:05:37 +02:00
config.locale = locale != null ? locale : Locale.getDefault();
2017-08-09 17:23:19 +02:00
_context.getResources().updateConfiguration(config, null);
}
// Find out if color above the given color should be light or dark. true if light
public boolean shouldColorOnTopBeLight(int colorOnBottomInt) {
return 186 > (((0.299 * Color.red(colorOnBottomInt))
+ ((0.587 * Color.green(colorOnBottomInt))
+ (0.114 * Color.blue(colorOnBottomInt)))));
}
2017-08-09 17:23:19 +02:00
public float px2dp(final float px) {
return px / _context.getResources().getDisplayMetrics().density;
}
public float dp2px(final float dp) {
return dp * _context.getResources().getDisplayMetrics().density;
2017-05-29 19:05:37 +02:00
}
}