Java tutorial
//--------------------------------------------------------------------------------------- // Copyright (c) 2001-2016 by PDFTron Systems Inc. All Rights Reserved. // Consult legal.txt regarding legal and license information. //--------------------------------------------------------------------------------------- package com.pdftron.pdf.utils; import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Point; import android.graphics.PointF; import android.graphics.RectF; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.StatFs; import android.provider.MediaStore; import android.provider.OpenableColumns; import android.support.annotation.NonNull; import android.text.Html; import android.text.method.LinkMovementMethod; import android.util.Base64; import android.util.Log; import android.view.Display; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; import com.pdftron.common.PDFNetException; import com.pdftron.pdf.tools.BuildConfig; import com.pdftron.pdf.tools.R; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; 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.text.NumberFormat; import java.util.Locale; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; public class Utils { /** * Checks if this device is running Honeycomb or higher. * * @return true if Honeycomb or higher, false otherwise. */ public static boolean isHoneycomb() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; } /** * Checks if this device is running any Honeycomb version (APIs 11, 12 or 13). * * @return true if any of the Honeycomb APIs, false otherwise. */ public static boolean isHoneycombOnly() { return Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB || Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB_MR1 || Build.VERSION.SDK_INT == Build.VERSION_CODES.HONEYCOMB_MR2; } public static boolean isHoneycombMR1() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1; } public static boolean isHoneycombMR2() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2; } public static boolean isIceCreamSandwich() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH; } public static boolean isJellyBean() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; } public static boolean isJellyBeanMR1() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; } public static boolean isJellyBeanMR2() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; } /** * Checks if this device is running KitKat or higher. * * @return true if KitKat or higher, false otherwise. */ public static boolean isKitKat() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; } public static boolean isKitKatOnly() { return Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT; } public static boolean isLollipop() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } public static boolean isMarshmallow() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } public static String copyResourceToTempFolder(Context context, int resId, boolean force, String resourceName) throws PDFNetException { if (context == null) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "copyResourceToTempFolder()", "Context cannot be null to initialize resource file."); } else { File resFile = new File(context.getFilesDir() + File.separator + "resourceName"); if (!resFile.exists() || force) { File filesDir = context.getFilesDir(); StatFs stat = new StatFs(filesDir.getPath()); long size = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); if (size < 2903023L) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "copyResourceToTempFolder()", "Not enough space available to copy resources file."); } Resources rs = context.getResources(); try { InputStream e = rs.openRawResource(resId); FileOutputStream fos = context.openFileOutput(resourceName, 0); byte[] buffer = new byte[1024]; int read; while ((read = e.read(buffer)) != -1) { fos.write(buffer, 0, read); } e.close(); fos.flush(); fos.close(); } catch (Resources.NotFoundException var13) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "initializeResource()", "Resource file ID does not exist."); } catch (FileNotFoundException var14) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "initializeResource()", "Resource file not found."); } catch (IOException var15) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "initializeResource()", "Error writing resource file to internal storage."); } catch (Exception var16) { throw new PDFNetException("", 0L, "com.pdftron.pdf.PDFNet", "initializeResource()", "Unknown error."); } } return context.getFilesDir().getAbsolutePath(); } } public static boolean isTablet(Context context) { boolean result = false; try { result = context.getResources().getBoolean(R.bool.isTablet); } catch (Exception e) { // Do nothing } return result; } // PDFViewCtrlTools utility methods public static com.pdftron.pdf.Rect convertFromPageRectToScreenRect(com.pdftron.pdf.PDFViewCtrl pdfViewCtrl, com.pdftron.pdf.Rect rect, int pageNum) throws PDFNetException { rect.normalize(); double x1 = rect.getX1(); double y1 = rect.getY1(); double x2 = rect.getX2(); double y2 = rect.getY2(); double[] pts1 = pdfViewCtrl.convPagePtToScreenPt(x1, y1, pageNum); double[] pts2 = pdfViewCtrl.convPagePtToScreenPt(x2, y2, pageNum); com.pdftron.pdf.Rect retRect = new com.pdftron.pdf.Rect(pts1[0], pts1[1], pts2[0], pts2[1]); retRect.normalize(); return retRect; } public static com.pdftron.pdf.Rect convertFromPageRectToScrollViewerRect( com.pdftron.pdf.PDFViewCtrl pdfViewCtrl, com.pdftron.pdf.Rect rect, int pageNum) throws PDFNetException { rect.normalize(); double x1 = rect.getX1(); double y1 = rect.getY1(); double x2 = rect.getX2(); double y2 = rect.getY2(); double[] pts1 = pdfViewCtrl.convPagePtToHorizonalScrollingPt(x1, y1, pageNum); double[] pts2 = pdfViewCtrl.convPagePtToHorizonalScrollingPt(x2, y2, pageNum); com.pdftron.pdf.Rect retRect = new com.pdftron.pdf.Rect(pts1[0], pts1[1], pts2[0], pts2[1]); return retRect; } public static void snapPointToRect(PointF point, RectF rect) { if (rect != null) { if (point.x < rect.left) { point.x = rect.left; } else if (point.x > rect.right) { point.x = rect.right; } if (point.y < rect.top) { point.y = rect.top; } else if (point.y > rect.bottom) { point.y = rect.bottom; } } } // check if the system language is Persian/Arabic public static boolean isSystemLanguagePerAra() { if (!isJellyBeanMR1()) { return false; } final int directionality = Character.getDirectionality(Locale.getDefault().getDisplayName().charAt(0)); if (directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT || directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC) { return true; } return false; } // check if layout direction is right-to-left public static boolean isRtlLayout(Context context) { if (isJellyBeanMR1()) { Configuration config = context.getResources().getConfiguration(); if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { return true; } } return false; } public static boolean isRightToLeftString(String str) { // decision is made based on the first character belonging to RTL/LTR unicode values // as defined in the Core (UnicodeUtils) if (str == null || str.length() == 0) { return false; } int sz = str.length(); for (int i = 0; i < sz; i++) { char u = str.charAt(i); if ((0x0590 <= u && u <= 0x05FF) || (0x0600 <= u && u <= 0x06FF) || (0x0750 <= u && u <= 0x077F) || (0xFB50 <= u && u <= 0xFDFF) || (0xFE70 <= u && u <= 0xFEFF)) { return true; } if ((0x0041 <= u && u <= 0x005A) || (0x0061 <= u && u <= 0x007A) || (0xFB00 <= u && u <= 0xFB06)) { return false; } } return false; } public static boolean hasRightToLeftChar(String str) { if (str == null || str.length() == 0) { return false; } int sz = str.length(); for (int i = 0; i < sz; i++) { char u = str.charAt(i); if ((0x0590 <= u && u <= 0x05FF) || (0x0600 <= u && u <= 0x06FF) || (0x0750 <= u && u <= 0x077F) || (0xFB50 <= u && u <= 0xFDFF) || (0xFE70 <= u && u <= 0xFEFF)) { return true; } } return false; } // get digits based on the Locale public static String getLocaleDigits(String input) { String output = ""; for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); if (ch >= '0' && ch <= '9') { output += String.format("%d", (int) ch - (int) '0'); } else { output += ch; } } return output; } /** * @param string the string to be checked against * @return true if the string is null or empty, false otherwise */ public static boolean isNullOrEmpty(String string) { return string == null || string.trim().isEmpty(); } public static String getUriColumnInfo(Context context, Uri contentUri, String column) { Cursor cursor = null; try { String[] proj = { column }; cursor = context.getContentResolver().query(contentUri, proj, // Which columns to return null, // WHERE clause; which rows to return (all rows) null, // WHERE clause selection arguments (none) null); // Order-by clause (ascending by name) if (null != cursor) { cursor.moveToFirst(); int column_index = cursor.getColumnIndexOrThrow(proj[0]); return cursor.getString(column_index); } return ""; } catch (Exception e) { AnalyticsHandlerAdapter.getInstance().sendException(e); } finally { if (cursor != null) { cursor.close(); } } return ""; } public static String getRealPathFromImageURI(Context context, Uri contentUri) { if (null == context || null == contentUri) { return ""; } Cursor cursor = null; try { // can post image String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, // Which columns to return null, // WHERE clause; which rows to return (all rows) null, // WHERE clause selection arguments (none) null); // Order-by clause (ascending by name) if (null != cursor) { cursor.moveToFirst(); int column_index = cursor.getColumnIndexOrThrow(proj[0]); return cursor.getString(column_index); } return ""; } catch (Exception e) { AnalyticsHandlerAdapter.getInstance().sendException(e); } finally { if (cursor != null) { cursor.close(); } } return ""; } public static Bitmap getBitmapFromImageUri(Context context, Uri imageUri, String backupFilepath) { if (null == context || null == imageUri) { return null; } try { Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), imageUri); if (bitmap == null) { // Add image to the output file if (!isNullOrEmpty(backupFilepath)) { FileInputStream fileInputStream = new FileInputStream(backupFilepath); bitmap = BitmapFactory.decodeStream(fileInputStream); } } return bitmap; } catch (Exception e) { AnalyticsHandlerAdapter.getInstance().sendException(e); } return null; } public static String getUriDisplayName(Context context, Uri contentUri) { String displayName = null; String[] projection = { OpenableColumns.DISPLAY_NAME }; Cursor cursor = null; if (contentUri.getScheme().equalsIgnoreCase("file")) { return contentUri.getLastPathSegment(); } try { cursor = context.getContentResolver().query(contentUri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { int nameIndex = cursor.getColumnIndexOrThrow(projection[0]); if (nameIndex >= 0) { displayName = cursor.getString(nameIndex); } } } catch (Exception e) { displayName = null; } if (cursor != null) { cursor.close(); } return displayName; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static void showToast(Context context, String string) { if (context != null) { Toast toast = Toast.makeText(context, string, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); return; } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static void showToast(Context context, int stringId) { if (context != null) { Toast toast = Toast.makeText(context, stringId, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); } } public static void showToast(Context context, String string, int duration) { if (context != null) { Toast toast = Toast.makeText(context, string, duration); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); } } public static void showToast(Context context, int stringId, int duration) { if (context != null) { Toast toast = Toast.makeText(context, stringId, duration); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static Toast showToast(Context context, Toast toast, String text, int duration) { if (toast != null) { toast.cancel(); } toast = Toast.makeText(context, text, duration); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); return toast; } public static Toast showToast(Context context, Toast toast, int stringId, int duration) { if (toast != null) { toast.cancel(); } toast = Toast.makeText(context, stringId, duration); if (Utils.isRtlLayout(context)) { toast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } toast.show(); return toast; } /** * Gets the size of the display, in pixels. * * @param context the Context * @param outSize A Point object to receive the size information */ public static void getDisplaySize(Context context, Point outSize) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); if (outSize == null) { outSize = new Point(); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(outSize); } else { outSize.set(display.getWidth(), display.getHeight()); } } public static boolean isOfficeDocument(String filePath) { String ext = FilenameUtils.getExtension(filePath); if (ext == null) return false; String[] fileTypes = Constants.FILE_NAME_EXTENSIONS_DOC; if (filePath != null) { for (String type : fileTypes) { if (ext.equalsIgnoreCase(type)) { return true; } } } return false; } public static boolean isImageFile(String filePath) { String ext = FilenameUtils.getExtension(filePath); if (ext == null) return false; String[] fileTypes = Constants.FILE_NAME_EXTENSIONS_IMAGE; if (filePath != null) { for (String type : fileTypes) { if (ext.equalsIgnoreCase(type)) { return true; } } } return false; } public static boolean isNotPDF(String filePath) { if (isOfficeDocument(filePath) || isImageFile(filePath)) return true; return false; } public static String decryptIt(Context context, String value) { String cryptoPass = context.getString(context.getApplicationInfo().labelRes); try { DESKeySpec keySpec = new DESKeySpec(cryptoPass.getBytes("UTF8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); byte[] encrypedPwdBytes = Base64.decode(value, Base64.DEFAULT); // cipher is not thread safe Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes)); String decrypedValue = new String(decrypedValueBytes); Log.d("MiscUtils", "Decrypted: " + value + " -> " + decrypedValue); return decrypedValue; } catch (Exception e) { Log.e(e.getClass().getName(), e.getMessage()); } return value; } public static String encryptIt(Context context, String value) { String cryptoPass = context.getString(context.getApplicationInfo().labelRes); try { DESKeySpec keySpec = new DESKeySpec(cryptoPass.getBytes("UTF8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); byte[] clearText = value.getBytes("UTF8"); // Cipher is not thread safe Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); String encrypedValue = Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT); Log.d("MiscUtils", "Encrypted: " + value + " -> " + encrypedValue); return encrypedValue; } catch (Exception e) { Log.d(e.getClass().getName(), e.getMessage()); } return value; } public static AlertDialog.Builder getAlertDialogNoTitleBuilder(Context context, int messageId) { return getAlertDialogBuilder(context, context.getResources().getString(messageId), ""); } public static AlertDialog.Builder getAlertDialogBuilder(Context context, int messageId, int titleId) { return getAlertDialogBuilder(context, context.getResources().getString(messageId), context.getResources().getString(titleId)); } public static AlertDialog.Builder getAlertDialogBuilder(Context context, String message, String title) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage(message).setCancelable(true); if (!isNullOrEmpty(title)) { builder.setTitle(title); } return builder; } static Toast sToast = null; static String sToastStr = null; @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static void showCommonToast(@NonNull Context context, String str, int duration) { if (sToast == null) { sToast = Toast.makeText(context, str, duration); } else if (str != sToastStr) { sToast.cancel(); sToast = Toast.makeText(context, str, duration); } sToastStr = str; if (Utils.isRtlLayout(context)) { sToast.getView().setTextDirection(View.TEXT_DIRECTION_RTL); } else { sToast.getView().setTextDirection(View.TEXT_DIRECTION_LTR); } sToast.show(); } public static void showCommonToast(@NonNull Context context, int stringId) { String str = context.getResources().getString(stringId); showCommonToast(context, str, Toast.LENGTH_LONG); } public static void showCommonToast(@NonNull Context context, int stringId, int duration) { String str = context.getResources().getString(stringId); showCommonToast(context, str, duration); } public static void showCommonToast(@NonNull Context context, String str) { showCommonToast(context, str, Toast.LENGTH_LONG); } public static void debugLogD(String tag, String msg) { if (BuildConfig.DEBUG) { Log.d(tag, msg); } } public static void debugLogV(String tag, String msg) { if (BuildConfig.DEBUG) { Log.v(tag, msg); } } /** * Get a human readable format of a byte size. * <p/> * See http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java * * @param bytes the number of bytes * @param si true for SI units or false for binary units * @return the human readable format of the byte size. */ public static String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) { if (Utils.isSystemLanguagePerAra()) { return String.format("%dB", bytes); // force put B in front of the number } return bytes + " B"; } int exp = (int) (Math.log(bytes) / Math.log(unit)); //String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + ""; if (Utils.isSystemLanguagePerAra()) { return String.format("%.1f%sB", bytes / Math.pow(unit, exp), pre); // force put B in front of the number } return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } public static Long getReadableByteValue(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes; int exp = (int) (Math.log(bytes) / Math.log(unit)); return (long) (bytes / Math.pow(unit, exp)); } public static String getReadableByteUnit(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return "B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); //String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + ""; return pre; } public static String getByteCount(long bytes) { return NumberFormat.getNumberInstance().format(bytes); } public static String getDisplayNameFromImageUri(Context context, Uri imageUri, String backupFilepath) { if (null == context || null == imageUri) { return null; } try { String filename = Utils.getUriColumnInfo(context, imageUri, MediaStore.Images.Media.DISPLAY_NAME); if (Utils.isNullOrEmpty(filename)) { if (!Utils.isNullOrEmpty(backupFilepath)) { filename = FilenameUtils.getBaseName(backupFilepath); } } return FilenameUtils.removeExtension(filename); } catch (Exception e) { AnalyticsHandlerAdapter.getInstance().sendException(e); } return null; } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static boolean isSdCardFile(Context context, File file) { if (!Utils.isKitKat()) { // not applicable for below kitkat return false; } if (file != null) { if (file.getParentFile() == null || file.getAbsolutePath().equals("/storage")) { // File cannot be on a SD-card return false; } final File storageDirectory = Environment.getExternalStorageDirectory(); final File[] rootDirs = context.getExternalFilesDirs(null); if (rootDirs != null && rootDirs.length > 0) { for (File dir : rootDirs) { if (dir != null) { try { if (!FilenameUtils.equals(storageDirectory.getAbsolutePath(), dir.getAbsolutePath()) && !FileUtils.directoryContains(storageDirectory, dir)) { while (dir.getParentFile() != null && !dir.getAbsolutePath().equalsIgnoreCase("/storage")) { if (FilenameUtils.equals(file.getAbsolutePath(), dir.getAbsolutePath()) || FileUtils.directoryContains(dir, file)) { // The current folder is on the SD-card return true; } dir = dir.getParentFile(); } } } catch (IOException ignored) { } } } } } return false; } public static void showAlertDialogWithLink(Context context, String message, String title) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage(Html.fromHtml(message)).setCancelable(true).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); if (title.length() > 0) { builder.setTitle(title); } final AlertDialog d = builder.create(); d.show(); // Make the textview clickable. Must be called after show() ((TextView) d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); } }