2017-05-29 19:05:37 +02:00
|
|
|
/*
|
2017-08-24 13:34:32 +02:00
|
|
|
* ------------------------------------------------------------------------------
|
|
|
|
* Gregor Santner <gsantner.github.io> wrote this. You can do whatever you want
|
|
|
|
* with it. If we meet some day, and you think it is worth it, you can buy me a
|
|
|
|
* coke in return. Provided as is without any kind of warranty. Do not blame or
|
|
|
|
* sue me if something goes wrong. No attribution required. - Gregor Santner
|
2017-05-29 19:05:37 +02:00
|
|
|
*
|
2017-08-24 13:34:32 +02:00
|
|
|
* License: Creative Commons Zero (CC0 1.0)
|
2017-05-29 19:05:37 +02:00
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
2017-09-09 17:09:04 +02:00
|
|
|
package net.gsantner.opoc.util;
|
2017-05-29 19:05:37 +02:00
|
|
|
|
|
|
|
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;
|
2017-08-24 13:34:32 +02:00
|
|
|
import android.content.res.Resources;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.BitmapFactory;
|
|
|
|
import android.graphics.Canvas;
|
2017-08-13 23:02:04 +02:00
|
|
|
import android.graphics.Color;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.graphics.Matrix;
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.graphics.drawable.Drawable;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.graphics.drawable.VectorDrawable;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.net.ConnectivityManager;
|
|
|
|
import android.net.NetworkInfo;
|
|
|
|
import android.net.Uri;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.os.Build;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.support.annotation.ColorRes;
|
|
|
|
import android.support.annotation.DrawableRes;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.support.annotation.Nullable;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.support.annotation.RawRes;
|
|
|
|
import android.support.annotation.StringRes;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.support.graphics.drawable.VectorDrawableCompat;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.support.v4.content.ContextCompat;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
2017-05-29 19:05:37 +02:00
|
|
|
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;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
2017-05-29 19:05:37 +02:00
|
|
|
import android.webkit.WebView;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.widget.ImageView;
|
2017-07-29 04:44:28 +02:00
|
|
|
import android.widget.TextView;
|
2017-09-09 17:09:04 +02:00
|
|
|
import android.widget.Toast;
|
2017-05-29 19:05:37 +02:00
|
|
|
|
|
|
|
import java.io.BufferedReader;
|
2017-09-09 17:09:04 +02:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.FileOutputStream;
|
2017-05-29 19:05:37 +02:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.util.Locale;
|
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
import static android.graphics.Bitmap.CompressFormat;
|
|
|
|
|
2017-08-24 13:34:32 +02:00
|
|
|
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "deprecation"})
|
2017-09-09 17:09:04 +02:00
|
|
|
public class ContextUtils {
|
2017-08-09 17:23:19 +02:00
|
|
|
//########################
|
|
|
|
//## Members, Constructors
|
|
|
|
//########################
|
|
|
|
protected Context _context;
|
2017-05-29 19:05:37 +02:00
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
public ContextUtils(Context context) {
|
2017-08-09 17:23:19 +02:00
|
|
|
_context = context;
|
2017-05-29 19:05:37 +02:00
|
|
|
}
|
|
|
|
|
2017-08-29 14:44:43 +02:00
|
|
|
public Context context() {
|
|
|
|
return _context;
|
2017-05-29 19:05:37 +02:00
|
|
|
}
|
|
|
|
|
2017-08-29 14:44:43 +02:00
|
|
|
//########################
|
|
|
|
//## Resources
|
|
|
|
//########################
|
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
|
|
|
}
|
|
|
|
|
2017-08-29 14:44:43 +02:00
|
|
|
public String str(@StringRes int strResId) {
|
|
|
|
return _context.getString(strResId);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2017-08-29 14:44:43 +02:00
|
|
|
public int getResId(final String type, final String name) {
|
|
|
|
return _context.getResources().getIdentifier(name, type, _context.getPackageName());
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean areResIdsAvailable(final String type, final String... names) {
|
|
|
|
for (String name : names) {
|
|
|
|
if (getResId(type, name) == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2017-05-29 19:05:37 +02:00
|
|
|
}
|
|
|
|
|
2017-08-29 14:44:43 +02:00
|
|
|
//########################
|
|
|
|
//## Methods
|
|
|
|
//########################
|
|
|
|
|
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 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-08-24 13:34:32 +02:00
|
|
|
* Get field from PackageId.BuildConfig
|
|
|
|
* May be helpful in libraries, where a access to
|
|
|
|
* BuildConfig would only get values of the library
|
|
|
|
* rather than the app ones
|
2017-08-09 17:23:19 +02:00
|
|
|
*/
|
|
|
|
public Object getBuildConfigValue(String fieldName) {
|
|
|
|
try {
|
2017-08-24 13:34:32 +02:00
|
|
|
Class<?> c = Class.forName(_context.getPackageName() + ".BuildConfig");
|
|
|
|
return c.getField(fieldName).get(null);
|
|
|
|
} catch (Exception e) {
|
2017-08-09 17:23:19 +02:00
|
|
|
e.printStackTrace();
|
2017-08-24 13:34:32 +02:00
|
|
|
return null;
|
2017-08-09 17:23:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
2017-08-24 13:34:32 +02:00
|
|
|
@SuppressWarnings("RestrictedApi")
|
2017-05-29 19:05:37 +02:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2017-09-09 17:09:04 +02:00
|
|
|
public boolean isConnectedToInternet(@Nullable @StringRes Integer warnMessageStringRes) {
|
|
|
|
final boolean result = isConnectedToInternet();
|
|
|
|
if (!result && warnMessageStringRes != null)
|
|
|
|
Toast.makeText(_context, _context.getString(warnMessageStringRes), Toast.LENGTH_SHORT).show();
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-05-29 19:05:37 +02:00
|
|
|
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) {
|
|
|
|
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
2017-08-29 14:44:43 +02:00
|
|
|
textView.setText(new SpannableString(htmlToSpanned(html)));
|
2017-07-29 04:44:28 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
2017-08-24 13:34:32 +02:00
|
|
|
return Resources.getSystem().getConfiguration().locale;
|
2017-05-29 19:05:37 +02:00
|
|
|
}
|
|
|
|
|
2017-08-24 13:34:32 +02:00
|
|
|
// en/de/de-rAt ; Empty string -> default locale
|
2017-05-29 19:05:37 +02:00
|
|
|
public void setAppLanguage(String androidLocaleString) {
|
|
|
|
Locale locale = getLocaleByAndroidCode(androidLocaleString);
|
2017-08-09 17:23:19 +02:00
|
|
|
Configuration config = _context.getResources().getConfiguration();
|
2017-08-24 13:34:32 +02:00
|
|
|
config.locale = (locale != null && !androidLocaleString.isEmpty())
|
|
|
|
? locale : Resources.getSystem().getConfiguration().locale;
|
2017-08-09 17:23:19 +02:00
|
|
|
_context.getResources().updateConfiguration(config, null);
|
|
|
|
}
|
|
|
|
|
2017-08-13 23:02:04 +02:00
|
|
|
// 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-29 14:44:43 +02:00
|
|
|
@SuppressWarnings("deprecation")
|
|
|
|
public Spanned htmlToSpanned(String html) {
|
|
|
|
Spanned result;
|
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
|
|
|
result = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
|
|
|
|
} else {
|
|
|
|
result = Html.fromHtml(html);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2017-08-24 13:34:32 +02:00
|
|
|
|
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
|
|
|
}
|
2017-09-09 17:09:04 +02:00
|
|
|
|
|
|
|
public void setViewVisible(View view, boolean visible) {
|
|
|
|
view.setVisibility(visible ? View.VISIBLE : View.GONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void setDrawableWithColorToImageView(ImageView imageView, @DrawableRes int drawableResId, @ColorRes int colorResId) {
|
|
|
|
imageView.setImageResource(drawableResId);
|
|
|
|
imageView.setColorFilter(ContextCompat.getColor(imageView.getContext(), colorResId));
|
|
|
|
}
|
|
|
|
|
|
|
|
public Bitmap drawableToBitmap(Drawable drawable) {
|
|
|
|
Bitmap bitmap = null;
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && (drawable instanceof VectorDrawable || drawable instanceof VectorDrawableCompat)) {
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
|
|
drawable = (DrawableCompat.wrap(drawable)).mutate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
|
|
|
|
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
|
|
|
Canvas canvas = new Canvas(bitmap);
|
|
|
|
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
|
|
|
drawable.draw(canvas);
|
|
|
|
} else if (drawable instanceof BitmapDrawable) {
|
|
|
|
bitmap = ((BitmapDrawable) drawable).getBitmap();
|
|
|
|
}
|
|
|
|
return bitmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Bitmap loadImageFromFilesystem(String imagePath, int maxDimen) {
|
|
|
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
|
|
|
options.inJustDecodeBounds = true;
|
|
|
|
BitmapFactory.decodeFile(imagePath, options);
|
|
|
|
options.inSampleSize = calculateInSampleSize(options, maxDimen);
|
|
|
|
options.inJustDecodeBounds = false;
|
|
|
|
return BitmapFactory.decodeFile(imagePath, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the scaling factor so the bitmap is maximal as big as the maxDimen
|
|
|
|
*
|
|
|
|
* @param options Bitmap-options that contain the current dimensions of the bitmap
|
|
|
|
* @param maxDimen Max size of the Bitmap (width or height)
|
|
|
|
* @return the scaling factor that needs to be applied to the bitmap
|
|
|
|
*/
|
|
|
|
public int calculateInSampleSize(BitmapFactory.Options options, int maxDimen) {
|
|
|
|
// Raw height and width of image
|
|
|
|
int height = options.outHeight;
|
|
|
|
int width = options.outWidth;
|
|
|
|
int inSampleSize = 1;
|
|
|
|
|
|
|
|
if (Math.max(height, width) > maxDimen) {
|
|
|
|
inSampleSize = Math.round(1f * Math.max(height, width) / maxDimen);
|
|
|
|
}
|
|
|
|
return inSampleSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Bitmap scaleBitmap(Bitmap bitmap, int maxDimen) {
|
|
|
|
int picSize = Math.min(bitmap.getHeight(), bitmap.getWidth());
|
|
|
|
float scale = 1.f * maxDimen / picSize;
|
|
|
|
Matrix matrix = new Matrix();
|
|
|
|
matrix.postScale(scale, scale);
|
|
|
|
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public File writeImageToFileJpeg(String path, String filename, Bitmap image) {
|
|
|
|
return writeImageToFile(path, filename, image, Bitmap.CompressFormat.JPEG, 95);
|
|
|
|
}
|
|
|
|
|
|
|
|
public File writeImageToFile(String path, String filename, Bitmap image, CompressFormat format, int quality) {
|
|
|
|
File imageFile = new File(path);
|
|
|
|
if (imageFile.exists() || imageFile.mkdirs()) {
|
|
|
|
imageFile = new File(path, filename);
|
|
|
|
|
|
|
|
FileOutputStream stream = null;
|
|
|
|
try {
|
|
|
|
stream = new FileOutputStream(imageFile); // overwrites this image every time
|
|
|
|
image.compress(format, quality, stream);
|
|
|
|
return imageFile;
|
|
|
|
} catch (FileNotFoundException ignored) {
|
|
|
|
} finally {
|
|
|
|
try {
|
|
|
|
if (stream != null) {
|
|
|
|
stream.close();
|
|
|
|
}
|
|
|
|
} catch (IOException ignored) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2017-05-29 19:05:37 +02:00
|
|
|
}
|