package net.the4thdimension.android; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.location.Location; import android.location.LocationManager; import android.location.LocationProvider; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.ParseException; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.Parcelable; import android.provider.MediaStore; import android.provider.MediaStore.Images.ImageColumns; import android.provider.MediaStore.Images.Media; import android.provider.MediaStore.MediaColumns; import android.provider.MediaStore.Video; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.telephony.TelephonyManager; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.StyleSpan; import android.util.Base64; import android.util.Log; import android.view.inputmethod.InputMethodManager; import android.widget.TextView; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.Random; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Provides convenience methods and abstractions to some tasks in Android * <p/> * <br/> * <br/> * * @author Jay */ public class Utils { private static final String TAG = Utils.class.getSimpleName(); static ProgressDialog mProgressDialog; /** * Shows a long time duration toast message. * * @param msg Message to be show in the toast. * @return Toast object just shown **/ public static Toast showToast(Context ctx, CharSequence msg) { return showToast(ctx, msg, Toast.LENGTH_LONG); } /** * Shows the message passed in the parameter in the Toast. * * @param msg Message to be show in the toast. * @param duration Duration in milliseconds for which the toast should be shown * @return Toast object just shown **/ public static Toast showToast(Context ctx, CharSequence msg, int duration) { Toast toast = Toast.makeText(ctx, msg, Toast.LENGTH_SHORT); toast.setDuration(duration); toast.show(); return toast; } /** * Checks if the Internet connection is available. * * @return Returns true if the Internet connection is available. False otherwise. **/ public static boolean isInternetAvailable(Context ctx) { // using received context (typically activity) to get SystemService causes memory link as this holds strong reference to that activity. // use application level context instead, which is available until the app dies. ConnectivityManager connectivityManager = (ConnectivityManager) ctx.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); // if network is NOT available networkInfo will be null // otherwise check if we are connected if (networkInfo != null && networkInfo.isConnected()) { return true; } return false; } /** * Checks if the SD Card is mounted on the device. **/ public static boolean isSdCardMounted() { String status = Environment.getExternalStorageState(); if (status != null && status.equals(Environment.MEDIA_MOUNTED)) { return true; } return false; } /** * Shows an alert dialog with the OK button. When the user presses OK button, the dialog * dismisses. **/ public static void showAlertDialog(Context context, @StringRes int titleResId, @StringRes int bodyResId) { showAlertDialog(context, context.getString(titleResId), context.getString(bodyResId), null); } /** * Shows an alert dialog with the OK button. When the user presses OK button, the dialog * dismisses. **/ public static void showAlertDialog(Context context, String title, String body) { showAlertDialog(context, title, body, null); } /** * Shows an alert dialog with OK button **/ public static void showAlertDialog(Context context, String title, String body, DialogInterface.OnClickListener okListener) { if (okListener == null) { okListener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }; } AlertDialog.Builder builder = new AlertDialog.Builder(context) .setMessage(body).setPositiveButton("OK", okListener); if (!TextUtils.isEmpty(title)) { builder.setTitle(title); } builder.show(); } /** * Serializes the Bitmap to Base64 * * @return Base64 string value of a {@linkplain android.graphics.Bitmap} passed in as a parameter * @throws NullPointerException If the parameter bitmap is null. **/ public static String toBase64(Bitmap bitmap) { if (bitmap == null) { throw new NullPointerException("Bitmap cannot be null"); } String base64Bitmap = null; ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] imageBitmap = stream.toByteArray(); base64Bitmap = Base64.encodeToString(imageBitmap, Base64.DEFAULT); return base64Bitmap; } /** * Converts the passed in drawable to Bitmap representation * * @throws NullPointerException If the parameter drawable is null. **/ public static Bitmap drawableToBitmap(Drawable drawable) { if (drawable == null) { throw new NullPointerException("Drawable to convert should NOT be null"); } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } if (drawable.getIntrinsicWidth() <= 0 && drawable.getIntrinsicHeight() <= 0) { return null; } Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } /** * Converts the given bitmap to {@linkplain java.io.InputStream}. * * @throws NullPointerException If the parameter bitmap is null. **/ public static InputStream bitmapToInputStream(Bitmap bitmap) throws NullPointerException { if (bitmap == null) { throw new NullPointerException("Bitmap cannot be null"); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); InputStream inputstream = new ByteArrayInputStream(baos.toByteArray()); return inputstream; } /** * Shows a progress dialog with a spinning animation in it. This method must preferably called * from a UI thread. * * @param ctx Activity context * @param title Title of the progress dialog * @param body Body/Message to be shown in the progress dialog * @param isCancellable True if the dialog can be cancelled on back button press, false otherwise **/ public static void showProgressDialog(Context ctx, String title, String body, boolean isCancellable) { showProgressDialog(ctx, title, body, null, isCancellable); } /** * Shows a progress dialog with a spinning animation in it. This method must preferably called * from a UI thread. * * @param ctx Activity context * @param title Title of the progress dialog * @param body Body/Message to be shown in the progress dialog * @param icon Icon to show in the progress dialog. It can be null. * @param isCancellable True if the dialog can be cancelled on back button press, false otherwise **/ public static void showProgressDialog(Context ctx, String title, String body, Drawable icon, boolean isCancellable) { if (ctx instanceof Activity) { if (!((Activity) ctx).isFinishing()) { mProgressDialog = ProgressDialog.show(ctx, title, body, true); mProgressDialog.setIcon(icon); mProgressDialog.setCancelable(isCancellable); } } } /** * Check if the {@link android.app.ProgressDialog} is visible in the UI. **/ public static boolean isProgressDialogVisible() { return (mProgressDialog != null); } /** * Dismiss the progress dialog if it is visible. **/ public static void dismissProgressDialog() { if (mProgressDialog != null) { mProgressDialog.dismiss(); } mProgressDialog = null; } /** * Gives the device independent constant which can be used for scaling images, manipulating view * sizes and changing dimension and display pixels etc. **/ public static float getDensityMultiplier(Context context) { return context.getResources().getDisplayMetrics().density; } /** * This method converts device specific pixels to density independent pixels. * * @param px A value in px (pixels) unit. Which we need to convert into db * @param context Context to get resources and device specific display metrics * @return A int value to represent dp equivalent to px value */ public static int getDip(int px, Context context) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (px * scale + 0.5f); } /** * Creates a confirmation dialog with Yes-No Button. By default the buttons just dismiss the * dialog. * * @param ctx * @param message Message to be shown in the dialog. * @param yesListener Yes click handler * @param noListener **/ public static void showConfirmDialog(Context ctx, String message, DialogInterface.OnClickListener yesListener, DialogInterface.OnClickListener noListener) { showConfirmDialog(ctx, message, yesListener, noListener, "Yes", "No"); } /** * Creates a confirmation dialog with Yes-No Button. By default the buttons just dismiss the * dialog. * * @param ctx * @param message Message to be shown in the dialog. * @param yesListener Yes click handler * @param noListener * @param yesLabel Label for yes button * @param noLabel Label for no button **/ public static void showConfirmDialog(Context ctx, String message, DialogInterface.OnClickListener yesListener, DialogInterface.OnClickListener noListener, String yesLabel, String noLabel) { AlertDialog.Builder builder = new AlertDialog.Builder(ctx); if (yesListener == null) { yesListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }; } if (noListener == null) { noListener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }; } builder.setMessage(message).setPositiveButton(yesLabel, yesListener).setNegativeButton(noLabel, noListener).show(); } /** * Creates a confirmation dialog that show a pop-up with button labeled as parameters labels. * * @param ctx {@link android.app.Activity} {@link android.content.Context} * @param message Message to be shown in the dialog. * @param dialogClickListener * @param positiveBtnLabel For e.g. "Yes" * @param negativeBtnLabel For e.g. "No" **/ public static void showDialog(Context ctx, String message, String positiveBtnLabel, String negativeBtnLabel, DialogInterface.OnClickListener dialogClickListener) { if (dialogClickListener == null) { throw new NullPointerException("Action listener cannot be null"); } AlertDialog.Builder builder = new AlertDialog.Builder(ctx); builder.setMessage(message).setPositiveButton(positiveBtnLabel, dialogClickListener).setNegativeButton(negativeBtnLabel, dialogClickListener).show(); } /** * Gets the version name of the application. For e.g. 1.9.3 **/ public static String getApplicationVersionNumber(Context context) { String versionName = null; if (context == null) { return versionName; } try { versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; } catch (NameNotFoundException e) { e.printStackTrace(); } return versionName; } /** * Gets the version code of the application. For e.g. Maverick Meerkat or 2013050301 **/ public static int getApplicationVersionCode(Context ctx) { int versionCode = 0; try { versionCode = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return versionCode; } /** * Gets the version number of the Android OS For e.g. 2.3.4 or 4.1.2 **/ public static String getOsVersion() { return Build.VERSION.RELEASE; } /** * Checks if the service with the given name is currently running on the device. * * @param serviceName Fully qualified name of the server. <br/> * For e.g. nl.changer.myservice.name **/ public static boolean isServiceRunning(Context ctx, String serviceName) { if (serviceName == null) { throw new NullPointerException("Service name cannot be null"); } // use application level context to avoid unnecessary leaks. ActivityManager manager = (ActivityManager) ctx.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (service.service.getClassName().equals(serviceName)) { return true; } } return false; } /** * Gets the device unique id called IMEI. Sometimes, this returns 00000000000000000 for the * rooted devices. **/ public static String getDeviceImei(Context ctx) { // use application level context to avoid unnecessary leaks. TelephonyManager telephonyManager = (TelephonyManager) ctx.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); return telephonyManager.getDeviceId(); } /** * Shares an application over the social network like Facebook, Twitter etc. * * @param sharingMsg Message to be pre-populated when the 3rd party app dialog opens up. * @param emailSubject Message that shows up as a subject while sharing through email. * @param title Title of the sharing options prompt. For e.g. "Share via" or "Share using" **/ public static void share(Context ctx, String sharingMsg, String emailSubject, String title) { Intent sharingIntent = new Intent(Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(Intent.EXTRA_TEXT, sharingMsg); sharingIntent.putExtra(Intent.EXTRA_SUBJECT, emailSubject); ctx.startActivity(Intent.createChooser(sharingIntent, title)); } /** * Checks the type of data connection that is currently available on the device. * * @return <code>ConnectivityManager.TYPE_*</code> as a type of internet connection on the * device. Returns -1 in case of error or none of * <code>ConnectivityManager.TYPE_*</code> is found. **/ public static int getDataConnectionType(Context ctx) { // use application level context to avoid unnecessary leaks. ConnectivityManager connectivityManager = (ConnectivityManager) ctx.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivityManager != null && connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null) { if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected()) { return ConnectivityManager.TYPE_MOBILE; } else if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) { return ConnectivityManager.TYPE_WIFI; } else return -1; } else return -1; } /** * Checks if the input parameter is a valid email. * * @param email * @return */ public static boolean isValidEmail(String email) { if (email == null) { return false; } final String emailPattern = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; Matcher matcher; Pattern pattern = Pattern.compile(emailPattern); matcher = pattern.matcher(email); if (matcher != null) { return matcher.matches(); } else { return false; } } @Nullable /** * Capitalizes each word in the string. * @param string * @return */ public static String capitalizeString(String string) { if (string == null) { return null; } char[] chars = string.toLowerCase().toCharArray(); boolean found = false; for (int i = 0; i < chars.length; i++) { if (!found && Character.isLetter(chars[i])) { chars[i] = Character.toUpperCase(chars[i]); found = true; } else if (Character.isWhitespace(chars[i]) || chars[i] == '.' || chars[i] == '\'') { // You // can add other // chars here found = false; } } // end for return String.valueOf(chars); } /** * Checks if the DB with the given name is present on the device. * * @param packageName * @param dbName * @return */ public static boolean isDatabasePresent(String packageName, String dbName) { SQLiteDatabase sqLiteDatabase = null; try { sqLiteDatabase = SQLiteDatabase.openDatabase("/data/data/" + packageName + "/databases/" + dbName, null, SQLiteDatabase.OPEN_READONLY); sqLiteDatabase.close(); } catch (SQLiteException e) { // database doesn't exist yet. e.printStackTrace(); Log.e(TAG, "The database does not exist." + e.getMessage()); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "Exception " + e.getMessage()); } return (sqLiteDatabase != null); } /** * Get the file path from the Media Content Uri for video, audio or images. * * @param mediaContentUri Media content Uri. **/ public static String getPathForMediaUri(Context context, Uri mediaContentUri) { Cursor cur = null; String path = null; try { String[] projection = {MediaColumns.DATA}; cur = context.getContentResolver().query(mediaContentUri, projection, null, null, null); if (cur != null && cur.getCount() != 0) { cur.moveToFirst(); path = cur.getString(cur.getColumnIndexOrThrow(MediaColumns.DATA)); } // Log.v( TAG, "#getRealPathFromURI Path: " + path ); } catch (Exception e) { e.printStackTrace(); } finally { if (cur != null && !cur.isClosed()) cur.close(); } return path; } public static ArrayList<String> toStringArray(JSONArray jsonArr) { if (jsonArr == null || jsonArr.length() == 0) { return null; } ArrayList<String> stringArray = new ArrayList<String>(); for (int i = 0, count = jsonArr.length(); i < count; i++) { try { String str = jsonArr.getString(i); stringArray.add(str); } catch (JSONException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } return stringArray; } /** * Convert a given list of {@link String} into a {@link org.json.JSONArray} **/ public static JSONArray toJSONArray(ArrayList<String> stringArr) { JSONArray jsonArr = new JSONArray(); for (int i = 0; i < stringArr.size(); i++) { String value = stringArr.get(i); jsonArr.put(value); } return jsonArr; } /** * Gets the data storage directory(pictures dir) for the device. If the external storage is not * available, this returns the reserved application data storage directory. SD Card storage will * be preferred over internal storage. * * @param dirName if the directory name is specified, it is created inside the DIRECTORY_PICTURES * directory. * @return Data storage directory on the device. Maybe be a directory on SD Card or internal * storage of the device. **/ public static File getStorageDirectory(Context ctx, String dirName) { if (TextUtils.isEmpty(dirName)) { dirName = "atemp"; } File f = null; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/" + dirName); } else { // media is removed, unmounted etc // Store image in // /data/data/<package-name>/cache/atemp/photograph.jpeg f = new File(ctx.getCacheDir() + "/" + dirName); } if (!f.exists()) { f.mkdirs(); } return f; } /** * Given a file name, this method creates a {@link java.io.File} on best chosen device storage and * returns the file object. You can get the file path using {@link java.io.File#getAbsolutePath()} **/ public static File getFile(Context ctx, String fileName) { File dir = getStorageDirectory(ctx, null); File f = new File(dir, fileName); return f; } /** * @return Path of the image file that has been written. * @deprecated Use {@link MediaUtils#writeImage(Context, byte[])} * Writes the given image to the external storage of the device. If external storage is not * available, the image is written to the application private directory **/ public static String writeImage(Context ctx, byte[] imageData) { final String FILE_NAME = "photograph.jpeg"; File dir = null; String filePath = null; OutputStream imageFileOS; dir = getStorageDirectory(ctx, null); File f = new File(dir, FILE_NAME); try { imageFileOS = new FileOutputStream(f); imageFileOS.write(imageData); imageFileOS.flush(); imageFileOS.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } filePath = f.getAbsolutePath(); return filePath; } /** * Inserts an image into {@link android.provider.MediaStore.Images.Media} content provider of the device. * * @return The media content Uri to the newly created image, or null if the image failed to be * stored for any reason. **/ public static String writeImageToMedia(Context ctx, Bitmap image, String title, String description) { // TODO: move to MediaUtils if (ctx == null) { throw new NullPointerException("Context cannot be null"); } return Media.insertImage(ctx.getContentResolver(), image, title, description); } /** * Gets the name of the application that has been defined in AndroidManifest.xml * * @throws android.content.pm.PackageManager.NameNotFoundException **/ public static String getApplicationName(Context ctx) throws NameNotFoundException { if (ctx == null) { throw new NullPointerException("Context cannot be null"); } final PackageManager packageMgr = ctx.getPackageManager(); ApplicationInfo appInfo = null; try { appInfo = packageMgr.getApplicationInfo(ctx.getPackageName(), PackageManager.SIGNATURE_MATCH); } catch (final NameNotFoundException e) { throw new NameNotFoundException(e.getMessage()); } final String applicationName = (String) (appInfo != null ? packageMgr.getApplicationLabel(appInfo) : "UNKNOWN"); return applicationName; } /** * Returns the URL without the query string **/ public static URL getPathFromUrl(URL url) { if (url != null) { String urlStr = url.toString(); String urlWithoutQueryString = urlStr.split("\\?")[0]; try { return new URL(urlWithoutQueryString); } catch (MalformedURLException e) { e.printStackTrace(); } } return null; } /** * Transforms Calendar to ISO 8601 string. **/ public static String fromCalendar(final Calendar calendar) { // TODO: move this method to DateUtils Date date = calendar.getTime(); String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(date); return formatted.substring(0, 22) + ":" + formatted.substring(22); } /** * Gets current date and time formatted as ISO 8601 string. **/ public static String now() { // TODO: move this method to DateUtils return fromCalendar(GregorianCalendar.getInstance()); } /** * Transforms ISO 8601 string to Calendar. **/ public static Calendar toCalendar(final String iso8601string) throws ParseException { // TODO: move this method to DateUtils Calendar calendar = GregorianCalendar.getInstance(); String s = iso8601string.replace("Z", "+00:00"); try { s = s.substring(0, 22) + s.substring(23); } catch (IndexOutOfBoundsException e) { // throw new org.apache.http.ParseException(); e.printStackTrace(); } Date date = null; try { date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s); } catch (java.text.ParseException e) { e.printStackTrace(); } calendar.setTime(date); return calendar; } /** * @param time ISO formatted time when the event occurred in local time zone. * @deprecated Totally bloated code. * Calculates the elapsed time after the given parameter date. **/ public static String getElapsedTime(String time) { TimeZone defaultTimeZone = TimeZone.getDefault(); // TODO: its advisable not to use this method as it changes the // timezone. // Change it at some time in future. TimeZone.setDefault(TimeZone.getTimeZone("UTC")); Date eventTime = DateUtils.parseDate(time); Date currentDate = new Date(); long diffInSeconds = (currentDate.getTime() - eventTime.getTime()) / 1000; String elapsed = ""; long seconds = diffInSeconds; long mins = diffInSeconds / 60; long hours = diffInSeconds / (60 * 60); long days = diffInSeconds / 86400; long weeks = diffInSeconds / 604800; long months = diffInSeconds / 2592000; // Log.v( TAG, "#getElapsedTime seconds: " + seconds + " mins: " + mins // + " hours: " + hours + " days: " + days ); if (seconds < 120) { elapsed = "a min ago"; } else if (mins < 60) { elapsed = mins + " mins ago"; } else if (hours < 24) { elapsed = hours + " " + (hours > 1 ? "hrs" : "hr") + " ago"; } else if (hours < 48) { elapsed = "a day ago"; } else if (days < 7) { elapsed = days + " days ago"; } else if (weeks < 5) { elapsed = weeks + " " + (weeks > 1 ? "weeks" : "week") + " ago"; } else if (months < 12) { elapsed = months + " " + (months > 1 ? "months" : "months") + " ago"; } else { elapsed = "more than a year ago"; } TimeZone.setDefault(defaultTimeZone); return elapsed; } /** * Set Mock Location for test device. DDMS cannot be used to mock location on an actual device. * So this method should be used which forces the GPS Provider to mock the location on an actual * device. **/ public static void setMockLocation(Context ctx, double longitude, double latitude) { // use application level context to avoid unnecessary leaks. LocationManager locationManager = (LocationManager) ctx.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); locationManager.addTestProvider(LocationManager.GPS_PROVIDER, "requiresNetwork" == "", "requiresSatellite" == "", "requiresCell" == "", "hasMonetaryCost" == "", "supportsAltitude" == "", "supportsSpeed" == "", "supportsBearing" == "", android.location.Criteria.POWER_LOW, android.location.Criteria.ACCURACY_FINE); Location newLocation = new Location(LocationManager.GPS_PROVIDER); newLocation.setLongitude(longitude); newLocation.setLatitude(latitude); newLocation.setTime(new Date().getTime()); newLocation.setAccuracy(500); locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true); locationManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis()); // http://jgrasstechtips.blogspot.it/2012/12/android-incomplete-location-object.html makeLocationObjectComplete(newLocation); locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, newLocation); } private static void makeLocationObjectComplete(Location newLocation) { Method locationJellyBeanFixMethod = null; try { locationJellyBeanFixMethod = Location.class.getMethod("makeComplete"); } catch (NoSuchMethodException e) { e.printStackTrace(); } if (locationJellyBeanFixMethod != null) { try { locationJellyBeanFixMethod.invoke(newLocation); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } /** * Gets the name of the day of the week. * * @param date ISO format date * @return The name of the day of the week **/ public static String getDayOfWeek(String date) { // TODO: move to DateUtils Date dateDT = DateUtils.parseDate(date); if (dateDT == null) { return null; } // Get current date Calendar c = Calendar.getInstance(); // it is very important to // set the date of // the calendar. c.setTime(dateDT); int day = c.get(Calendar.DAY_OF_WEEK); String dayStr = null; switch (day) { case Calendar.SUNDAY: dayStr = "Sunday"; break; case Calendar.MONDAY: dayStr = "Monday"; break; case Calendar.TUESDAY: dayStr = "Tuesday"; break; case Calendar.WEDNESDAY: dayStr = "Wednesday"; break; case Calendar.THURSDAY: dayStr = "Thursday"; break; case Calendar.FRIDAY: dayStr = "Friday"; break; case Calendar.SATURDAY: dayStr = "Saturday"; break; } return dayStr; } /** * Gets random color integer **/ public static int getRandomColor() { Random random = new Random(); int red = random.nextInt(255); int green = random.nextInt(255); int blue = random.nextInt(255); return Color.argb(255, red, green, blue); } /** * Converts a given bitmap to byte array */ public static byte[] toBytes(Bitmap bmp) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); return stream.toByteArray(); } /** * Resizes an image to the given width and height parameters Prefer using * * @param sourceBitmap Bitmap to be resized * @param newWidth Width of resized bitmap * @param newHeight Height of the resized bitmap */ public static Bitmap resizeImage(Bitmap sourceBitmap, int newWidth, int newHeight, boolean filter) { // TODO: move this method to ImageUtils if (sourceBitmap == null) { throw new NullPointerException("Bitmap to be resized cannot be null"); } Bitmap resized = null; if (sourceBitmap.getWidth() < sourceBitmap.getHeight()) { // image is portrait resized = Bitmap.createScaledBitmap(sourceBitmap, newHeight, newWidth, true); } else { // image is landscape resized = Bitmap.createScaledBitmap(sourceBitmap, newWidth, newHeight, true); } resized = Bitmap.createScaledBitmap(sourceBitmap, newWidth, newHeight, true); return resized; } /** * <br/> * <br/> * * @param compressionFactor Powers of 2 are often faster/easier for the decoder to honor */ public static Bitmap compressImage(Bitmap sourceBitmap, int compressionFactor) { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inPreferredConfig = Config.ARGB_8888; opts.inSampleSize = compressionFactor; if (Build.VERSION.SDK_INT >= 10) { opts.inPreferQualityOverSpeed = true; } ByteArrayOutputStream stream = new ByteArrayOutputStream(); sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); Bitmap image = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, opts); return image; } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and // width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will // guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } /** * Provide the height to which the sourceImage is to be resized. This method will calculate the * resultant height. Use scaleDownBitmap from {@link Utils} wherever possible */ public Bitmap resizeImageByHeight(int height, Bitmap sourceImage) { // TODO: move this method to ImageUtils int widthO = 0; // original width int heightO = 0; // original height int widthNew = 0; int heightNew = 0; widthO = sourceImage.getWidth(); heightO = sourceImage.getHeight(); heightNew = height; // Maintain the aspect ratio // of the original banner image. widthNew = (heightNew * widthO) / heightO; return Bitmap.createScaledBitmap(sourceImage, widthNew, heightNew, true); } /** * Checks if the url is valid */ public static boolean isValidURL(String url) { URL urlObj; try { urlObj = new URL(url); } catch (MalformedURLException e) { return false; } try { urlObj.toURI(); } catch (URISyntaxException e) { return false; } return true; } @Nullable /** * @return Lower case string for one of above listed media type * @deprecated Use {@link MediaUtils#getMediaType(Uri)} * Get the type of the media. Audio, Video or Image. */ public static String getMediaType(String contentType) { if (isMedia(contentType)) { if (isVideo(contentType)) { return "video"; } else if (isAudio(contentType)) { return "audio"; } else if (isImage(contentType)) { return "image"; } else { return null; } } else { return null; } } /** * @param mimeType standard MIME type of the data. * @deprecated {@link MediaUtils#isMedia(String)} * Identifies if the content represented by the parameter mimeType is media. Image, Audio and * Video is treated as media by this method. You can refer to standard MIME type here. <a * href="http://www.iana.org/assignments/media-types/media-types.xhtml" >Standard MIME * types.</a> */ public static boolean isMedia(String mimeType) { boolean isMedia = false; if (mimeType != null) { if (mimeType.startsWith("image/") || mimeType.startsWith("video/") || mimeType.startsWith("audio/")) { isMedia = true; } } else { isMedia = false; } return isMedia; } /** * Gets the Uri without the fragment. For e.g if the uri is * content://com.android.storage/data/images/48829#is_png the part after '#' is called as * fragment. This method strips the fragment and returns the url. */ public static String removeUriFragment(String url) { if (url == null || url.length() == 0) { return null; } String[] arr = url.split("#"); if (arr.length == 2) { return arr[0]; } else { return url; } } /** * Removes the parameters from the query from the uri */ public static String removeQueryParameters(Uri uri) { assert (uri.getAuthority() != null); assert (uri.getPath() != null); Uri.Builder builder = new Uri.Builder(); builder.scheme(uri.getScheme()); builder.encodedAuthority(uri.getAuthority()); builder.encodedPath(uri.getPath()); return builder.build().toString(); } /** * @deprecated Use {@link MediaUtils#isImage(String)} * Returns true if the mime type is a standard image mime type */ public static boolean isImage(String mimeType) { if (mimeType != null) { if (mimeType.startsWith("image/")) { return true; } else { return false; } } else { return false; } } /** * @deprecated Use {@link MediaUtils#isAudio(String)} * Returns true if the mime type is a standard audio mime type */ public static boolean isAudio(String mimeType) { if (mimeType != null) { if (mimeType.startsWith("audio/")) { return true; } else { return false; } } else { return false; } } /** * @deprecated Use {@link MediaUtils#isVideo(String)} * Returns true if the mime type is a standard video mime type */ public static boolean isVideo(String mimeType) { if (mimeType != null) { if (mimeType.startsWith("video/")) { return true; } else { return false; } } else { return false; } } @Nullable /** * @deprecated This is a monster that will lead to OutOfMemory exception some day and the world * will come to an end. * Gets the media data from the one of the following media {@link android.content.ContentProvider} This method * should not be called from the main thread of the application. Calling this method may have * performance issues as this may allocate a huge memory array. * <ul> * <li>{@link android.provider.MediaStore.Images.Media}</li> * <li>{@link android.provider.MediaStore.Audio.Media}</li> * <li>{@link android.provider.MediaStore.Video.Media}</li> * </ul> * * @param context Context object * @param uri Media content uri of the image, audio or video resource */ public static byte[] getMediaData(Context context, Uri uri) { if (uri == null) { throw new NullPointerException("Uri cannot be null"); } Cursor cursor = context.getContentResolver().query(uri, new String[]{Media.DATA}, null, null, null); byte[] data = null; try { if (cursor != null && cursor.getCount() > 0) { if (cursor.moveToNext()) { String path = cursor.getString(cursor.getColumnIndex(Media.DATA)); try { File file = new File(path); FileInputStream fileInputStream = new FileInputStream(file); data = readStreamToBytes(fileInputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } // Log.v( TAG, "#getVideoData byte.size: " + data.length ); } // end while } else { Log.e(TAG, "#getMediaData cur is null or blank"); } } finally { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } return data; } /** * Convert {@linkplain java.io.InputStream} to byte array. * * @throws NullPointerException If input parameter {@link java.io.InputStream} is null **/ public static byte[] readStreamToBytes(InputStream inputStream) { if (inputStream == null) { throw new NullPointerException("InputStream is null"); } byte[] bytesData = null; BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(inputStream)); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[16384]; while ((nRead = inputStream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); bytesData = buffer.toByteArray(); // Log.d( TAG, "#readStream data: " + data ); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); if (inputStream != null) inputStream.close(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } // finally return bytesData; } /** * @param mediaUri uri to the media resource. For e.g. content://media/external/images/media/45490 or * content://media/external/video/media/45490 * @return Size in bytes * @deprecated Use {@link MediaUtils#getMediaSize(Context, Uri)} * Gets the size of the media resource pointed to by the paramter mediaUri. * <p/> * Known bug: for unknown reason, the image size for some images was found to be 0 **/ public static long getMediaSize(Context context, Uri mediaUri) { Cursor cur = context.getContentResolver().query(mediaUri, new String[]{Media.SIZE}, null, null, null); long size = -1; try { if (cur != null && cur.getCount() > 0) { while (cur.moveToNext()) { size = cur.getLong(cur.getColumnIndex(Media.SIZE)); // for unknown reason, the image size for image was found to // be 0 // Log.v( TAG, "#getSize byte.size: " + size ); if (size == 0) Log.w(TAG, "#getSize The media size was found to be 0. Reason: UNKNOWN"); } // end while } else if (cur.getCount() == 0) { Log.e(TAG, "#getMediaSize cur size is 0. File may not exist"); } else { Log.e(TAG, "#getMediaSize cur is null"); } } finally { if (cur != null && !cur.isClosed()) { cur.close(); } } return size; } /** * @deprecated {@link MediaUtils#getMediaFileName(Context, Uri)} * Gets media file name. **/ public static String getMediaFileName(Context ctx, Uri mediaUri) { String colName = MediaColumns.DISPLAY_NAME; Cursor cur = ctx.getContentResolver().query(mediaUri, new String[]{colName}, null, null, null); String dispName = null; try { if (cur != null && cur.getCount() > 0) { while (cur.moveToNext()) { dispName = cur.getString(cur.getColumnIndex(colName)); // for unknown reason, the image size for image was found to // be 0 // Log.v( TAG, "#getMediaFileName byte.size: " + size ); if (TextUtils.isEmpty(colName)) { Log.w(TAG, "#getMediaFileName The file name is blank or null. Reason: UNKNOWN"); } } // end while } else if (cur != null && cur.getCount() == 0) { Log.e(TAG, "#getMediaFileName File may not exist"); } else { Log.e(TAG, "#getMediaFileName cur is null"); } } finally { if (cur != null && !cur.isClosed()) { cur.close(); } } return dispName; } @Nullable /** * @deprecated Use {@link MediaUtils#getMediaType(Uri)} * Gets media type from the Uri. */ public static String getMediaType(Uri uri) { if (uri == null) { return null; } String uriStr = uri.toString(); if (uriStr.contains("video")) { return "video"; } else if (uriStr.contains("audio")) { return "audio"; } else if (uriStr.contains("image")) { return "image"; } else { return null; } } /** * @param sourceText String to be converted to bold. * @deprecated Use {@link #toBold(String, String)} * Returns {@link android.text.SpannableString} in Bold typeface */ public static SpannableStringBuilder toBold(String sourceText) { if (sourceText == null) { throw new NullPointerException("String to convert cannot be bold"); } final SpannableStringBuilder sb = new SpannableStringBuilder(sourceText); // Span to set text color to some RGB value final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); // set text bold sb.setSpan(bss, 0, sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); return sb; } /** * Typefaces the string as bold. * If sub-string is null, entire string will be typefaced as bold and returned. * * @param string * @param subString The subString within the string to bold. Pass null to bold entire string. * @return {@link android.text.SpannableString} */ public static SpannableStringBuilder toBold(String string, String subString) { if (TextUtils.isEmpty(string)) { return new SpannableStringBuilder(""); } SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(string); StyleSpan bss = new StyleSpan(Typeface.BOLD); if (subString != null) { int substringNameStart = string.toLowerCase().indexOf(subString); if (substringNameStart > -1) { spannableBuilder.setSpan(bss, substringNameStart, substringNameStart + subString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { // set entire text to bold spannableBuilder.setSpan(bss, 0, spannableBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); } return spannableBuilder; } /** * Formats given size in bytes to KB, MB, GB or whatever. This will work up to 1000 TB */ public static String formatSize(long size) { if (size <= 0) return "0"; final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"}; int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } /** * Formats given size in bytes to KB, MB, GB or whatever. Preferably use this method for * performance efficiency. * * @param si Controls byte value precision. If true, formatting is done using approx. 1000 Uses * 1024 if false. **/ public static String formatSize(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) { return bytes + " B"; } int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } /** * Creates the uri to a file located on external storage or application internal storage. */ public static Uri createUri(Context ctx) { File root = getStorageDirectory(ctx, null); root.mkdirs(); File file = new File(root, Long.toString(new Date().getTime())); Uri uri = Uri.fromFile(file); return uri; } /** * @param ctx * @param savingUri * @param durationInSeconds * @return * @deprecated Use {@link MediaUtils#createTakeVideoIntent(Activity, Uri, int)} * Creates an intent to take a video from camera or gallery or any other application that can * handle the intent. */ public static Intent createTakeVideoIntent(Activity ctx, Uri savingUri, int durationInSeconds) { if (savingUri == null) { throw new NullPointerException("Uri cannot be null"); } final List<Intent> cameraIntents = new ArrayList<Intent>(); final Intent captureIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); final PackageManager packageManager = ctx.getPackageManager(); final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); for (ResolveInfo res : listCam) { final String packageName = res.activityInfo.packageName; final Intent intent = new Intent(captureIntent); intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); intent.setPackage(packageName); intent.putExtra(MediaStore.EXTRA_OUTPUT, savingUri); intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationInSeconds); cameraIntents.add(intent); } // Filesystem. final Intent galleryIntent = new Intent(); galleryIntent.setType("video/*"); galleryIntent.setAction(Intent.ACTION_GET_CONTENT); // Chooser of filesystem options. final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source"); // Add the camera options. chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{})); return chooserIntent; } /** * @param savingUri Uri to store a high resolution image at. If the user takes the picture using the * camera the image will be stored at this uri. * @deprecated Use {@link MediaUtils#createTakePictureIntent(Activity, Uri)} * Creates a ACTION_IMAGE_CAPTURE photo & ACTION_GET_CONTENT intent. This intent will be * aggregation of intents required to take picture from Gallery and Camera at the minimum. The * intent will also be directed towards the apps that are capable of sourcing the image data. * For e.g. Dropbox, Astro file manager. **/ public static Intent createTakePictureIntent(Activity ctx, Uri savingUri) { if (savingUri == null) { throw new NullPointerException("Uri cannot be null"); } final List<Intent> cameraIntents = new ArrayList<Intent>(); final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); final PackageManager packageManager = ctx.getPackageManager(); final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0); for (ResolveInfo res : listCam) { final String packageName = res.activityInfo.packageName; final Intent intent = new Intent(captureIntent); intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); intent.setPackage(packageName); intent.putExtra(MediaStore.EXTRA_OUTPUT, savingUri); cameraIntents.add(intent); } // Filesystem. final Intent galleryIntent = new Intent(); galleryIntent.setType("image/*"); galleryIntent.setAction(Intent.ACTION_GET_CONTENT); // Chooser of filesystem options. final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source"); // Add the camera options. chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{})); return chooserIntent; } @Nullable /** * @deprecated Use {@link MediaUtils#createImageUri(Context)} * Creates external content:// scheme uri to save the images at. The image saved at this * {@link android.net.Uri} will be visible via the gallery application on the device. */ public static Uri createImageUri(Context ctx) throws IOException { if (ctx == null) { throw new NullPointerException("Context cannot be null"); } Uri imageUri = null; ContentValues values = new ContentValues(); values.put(MediaColumns.TITLE, ""); values.put(ImageColumns.DESCRIPTION, ""); imageUri = ctx.getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values); return imageUri; } @Nullable /** * @deprecated Use {@link MediaUtils#createVideoUri(Context)} * Creates external content:// scheme uri to save the videos at. */ public static Uri createVideoUri(Context ctx) throws IOException { if (ctx == null) { throw new NullPointerException("Context cannot be null"); } Uri imageUri; ContentValues values = new ContentValues(); values.put(MediaColumns.TITLE, ""); values.put(ImageColumns.DESCRIPTION, ""); imageUri = ctx.getContentResolver().insert(Video.Media.EXTERNAL_CONTENT_URI, values); return imageUri; } @Nullable /** * * @deprecated Use {#setTextValues} or {#getNullEmptyCheckedValue} * Get the correctly appended name from the given name parameters * * @param firstName * First name * @param lastName * Last name * * @return Returns correctly formatted full name. Returns null if both the values are null. **/ public static String getName(String firstName, String lastName) { if (!TextUtils.isEmpty(firstName) && !TextUtils.isEmpty(lastName)) { return firstName + " " + lastName; } else if (!TextUtils.isEmpty(firstName)) { return firstName; } else if (!TextUtils.isEmpty(lastName)) { return lastName; } else { return null; } } public static Bitmap roundBitmap(Bitmap bmp, int radius) { Bitmap sbmp; if (bmp.getWidth() != radius || bmp.getHeight() != radius) { sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false); } else { sbmp = bmp; } Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight()); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.parseColor("#BAB399")); canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f, sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(sbmp, rect, rect, paint); return output; } /** * Checks if given url is a relative path. * * @param url * @return false if parameter url is null or false */ public static final boolean isRelativeUrl(String url) { if (TextUtils.isEmpty(url)) { return false; } Uri uri = Uri.parse(url); return uri.getScheme() == null; } /** * Checks if the parameter {@link android.net.Uri} is a content uri. **/ public static boolean isContentUri(Uri uri) { if (!uri.toString().contains("content://")) { return false; } else { return true; } } /** * Hides the already popped up keyboard from the screen. * * @param context */ public static void hideKeyboard(Context context) { try { // use application level context to avoid unnecessary leaks. InputMethodManager inputManager = (InputMethodManager) context.getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow(((Activity) context).getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } catch (Exception e) { Log.e(TAG, "Sigh, cant even hide keyboard " + e.getMessage()); } } /** * Checks if the build version passed as the parameter is * lower than the current build version. * * @param buildVersion One of the values from {@link android.os.Build.VERSION_CODES} * @return */ public static boolean isBuildBelow(int buildVersion) { if (Build.VERSION.SDK_INT < buildVersion) return true; else return false; } /** * Sets the two parameter values to the parameter {@link android.widget.TextView} * in null-safe and empty-safe way. Such method can be used when setting firstname-lastname * to a textview in the UI. * * @param textView * @param firstValue String "null" will be treated as null value. * @param secondValue String "null" will be treated as null value. */ public static void setTextValues(@NonNull TextView textView, @Nullable String firstValue, @Nullable String secondValue) { String nullEmptyCheckedVal = getNullEmptyCheckedValue(firstValue, secondValue, null); textView.setText(nullEmptyCheckedVal); } @Nullable /** * Returns concatenated values of atleast to or more strings provided to it * in a null safe manner. * @param firstValue * @param secondValue * @param delimiter Delimiter to be used to concatnate the parameter strings. If null, space characer will be used. * @param moreValues Optional * @return */ public static String getNullEmptyCheckedValue(@Nullable String firstValue, @Nullable String secondValue, @Nullable String delimiter, String... moreValues) { if (TextUtils.isEmpty(delimiter)) { delimiter = " "; } StringBuilder builder = new StringBuilder(); if (!TextUtils.isEmpty(firstValue) && !firstValue.equalsIgnoreCase("null") && secondValue != null && !secondValue.equalsIgnoreCase("null")) { builder.append(firstValue); builder.append(delimiter); builder.append(secondValue); } else if (!TextUtils.isEmpty(firstValue) && !firstValue.equalsIgnoreCase("null")) { builder.append(firstValue); } else if (!TextUtils.isEmpty(secondValue) && !secondValue.equalsIgnoreCase("null")) { builder.append(secondValue); } if (moreValues != null) { for (String value : moreValues) { if (!TextUtils.isEmpty(value) && !value.equalsIgnoreCase("null")) { builder.append(delimiter); builder.append(value); } } } return builder.toString(); } @Nullable /** * Partially capitalizes the string from paramter start and offset. * * @param string String to be formatted * @param start Starting position of the substring to be capitalized * @param offset Offset of characters to be capitalized * @return */ public static String capitalizeString(String string, int start, int offset) { if (TextUtils.isEmpty(string)) { return null; } String formattedString = string.substring(start, offset).toUpperCase() + string.substring(offset, string.length()); return formattedString; } @Nullable /** * Generates SHA-512 hash for given binary data. * @param stringToHash * @return */ public static String getSha512Hash(String stringToHash) { if (stringToHash == null) { return null; } else { return getSha512Hash(stringToHash.getBytes()); } } @Nullable /** * Generates SHA-512 hash for given binary data. */ public static String getSha512Hash(byte[] dataToHash) { MessageDigest md = null; try { md = MessageDigest.getInstance("SHA-512"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } if (md != null) { md.update(dataToHash); byte byteData[] = md.digest(); String base64 = Base64.encodeToString(byteData, Base64.DEFAULT); return base64; } return null; } @Nullable /** * Gets the extension of a file. */ public static String getExtension(File file) { String ext = null; String s = file.getName(); int i = s.lastIndexOf('.'); if (i > 0 && i < s.length() - 1) { ext = s.substring(i + 1).toLowerCase(); } return ext; } }