package oak.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.io.IOException;
import java.util.HashMap;
import java.util.regex.Pattern;
/**
* Created by ericrichardson on 11/13/14.
*/
public class OakUtils {
private static final String TAG = OakUtils.class.getSimpleName();
private static HashMap<String, Typeface> mFontMap;
private OakUtils() {
}
/**
* @param context Context for fetching Typeface
* @param fontFileName Typeface to fetch. Must match a typeface name in /assets/fonts
* @return Typeface
*/
public static Typeface getStaticTypeFace(Context context, String fontFileName) {
if (mFontMap == null) {
initializeFontMap(context);
}
Typeface typeface = mFontMap.get(fontFileName);
if (typeface == null) {
throw new IllegalArgumentException(
"Font name must match file name in assets/fonts/ directory: " + fontFileName);
}
return typeface;
}
private static void initializeFontMap(Context context) {
mFontMap = new HashMap<String, Typeface>();
AssetManager assetManager = context.getAssets();
try {
String[] fontFileNames = assetManager.list("fonts");
for (String fontFileName : fontFileNames) {
Log.d(TAG, "Found font in assets: " + fontFileName);
Typeface typeface = Typeface.createFromAsset(assetManager, "fonts/" + fontFileName);
mFontMap.put(fontFileName, typeface);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Returns a formatted String to be used in places like an ActionBar
*
* @param context Context for fetching Typeface
* @param text text to be formatted
* @param typeface typeface to convert the text into.
* @return formatted String.
*/
public static SpannableString getTypefaceFormattedText(Context context, String text, String typeface) {
//TODO Make it not crash on terrible LG devices
SpannableString s = new SpannableString(text);
s.setSpan(new FontTypefaceSpan(context, typeface), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return s;
}
/**
* Given a View, this method sets the Typeface on every TextView contained within that View
*
* @param root View to check
* @param ctx Context for fetching Typeface
* @param typeface Typeface to set. Must match a typeface name in /assets/fonts
*/
public static void changeFonts(View root, Context ctx, String typeface) {
Typeface tf = getStaticTypeFace(ctx, typeface);
if (root instanceof TextView) {
((TextView) root).setTypeface(tf);
} else if (root instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) root).getChildCount(); i++) {
changeFonts(((ViewGroup) root).getChildAt(i), ctx, typeface);
}
}
}
/**
* Method that determines whether a specified package is installed on the device
*
* @param ctx Context for package manager
* @param packageName Target package name
* @return boolean of whether packageName is installed
*/
public static boolean isPackageInstalled(Context ctx, String packageName) {
try {
ApplicationInfo info = ctx.getPackageManager().getApplicationInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
"(?:(?:\\r\\n" +
")?[ \\t])*(?:(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)*\\<(?:(?:\\r\\n" +
")?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*(?:,@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*)*:(?:(?:\\r\\n" +
")?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*\\>(?:(?:\\r\\n" +
")?[ \\t])*)|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)*:(?:(?:\\r\\n" +
")?[ \\t])*(?:(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)*\\<(?:(?:\\r\\n" +
")?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*(?:,@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*)*:(?:(?:\\r\\n" +
")?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*\\>(?:(?:\\r\\n" +
")?[ \\t])*)(?:,\\s*(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)*\\<(?:(?:\\r\\n" +
")?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*(?:,@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*)*:(?:(?:\\r\\n" +
")?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n" +
")?[ \\t]))*\"(?:(?:\\r\\n" +
")?[ \\t])*))*@(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*)(?:\\.(?:(?:\\r\\n" +
")?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n" +
")?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n" +
")?[ \\t])*))*\\>(?:(?:\\r\\n" +
")?[ \\t])*))*)?;\\s*)"
);
/**
* Method to determine whether string is a valid email address
*
* @param email email to verify
*/
public static boolean isValidEmail(String email) {
return EMAIL_ADDRESS_PATTERN.matcher(email).matches();
}
private static final Pattern PHONE_NUMBER = Pattern.compile("/(?:(?:\\+?1\\s*(?:[.-]\\s*)?)?(?:(\\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\\s*(?:[.-]\\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\\s*(?:[.-]\\s*)?([0-9]{4})/");
/**
* Method to determine whether string is a valid phone number
*
* @param phone phone number to verify
*/
public static boolean isValidPhone(String phone) {
return PHONE_NUMBER.matcher(phone).matches();
}
}