package com.aincc.lib.util; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.text.DecimalFormat; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import org.apache.commons.lang3.StringUtils; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.StatFs; import android.telephony.TelephonyManager; import android.view.Display; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.ImageView; import com.aincc.lib.charset.Charsets; import com.aincc.lib.ui.anim.Animationz; /** * * <h3><b>Utils</b></h3></br> * * @author aincc@barusoft.com * @version 1.0.0 * @since 1.0.0 */ public class Utils { public static final int IO_BUFFER_SIZE = 8 * 1024; private Utils() { }; /** * 전화번호 가져오기 * * @param context * @return the phone number */ public static String getPhoneNumber(Context context) { String number = null; try { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); number = telephonyManager.getLine1Number(); } catch (Exception e) { e.printStackTrace(); } return number; } /** * IMEI 가져오기 (International Mobile Equipment Identity) * * @param context * @return the IMEI number */ public static String getIMEI(Context context) { String imei = null; try { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); imei = telephonyManager.getDeviceId(); } catch (Exception e) { e.printStackTrace(); } return imei; } /** * UUID 가져오기 * * @param context * @return the UUID number */ public static UUID getUUID(Context context) { final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); final String tmDevice, tmSerial, androidId; tmDevice = "" + tm.getDeviceId(); tmSerial = "" + tm.getSimSerialNumber(); androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode()); return deviceUuid; } /** * 액정 가로길이 * * @param context * @return the LCD width */ @TargetApi(13) public static int getLCDWidth(Context context) { Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); Point outSize = null; display.getSize(outSize); return (null != outSize ? outSize.x : 0); } /** * 액정 세로길이 * * @param context * @return the LCD height */ @TargetApi(13) public static int getLCDHeight(Context context) { Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); Point outSize = null; display.getSize(outSize); return (null != outSize ? outSize.y : 0); } /** * OS 버전 정보 가져오기 * * @return OS version */ public static String getOSVersion() { return android.os.Build.VERSION.RELEASE; } /** * Program 버전 정보 가져오기 * * @since 1.0.0 * @param context * @return */ public static String getProgramVersion(Context context) { String version = ""; try { PackageInfo i = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); version = i.versionName; } catch (NameNotFoundException e) { } return version; } /** * 화면켜짐 유지 플래그 설정 (각 액티비티에 공통 적용하여야 정상 반영됨.) * * @since 1.0.0 * @param context * 액티비티의 컨텍스트 * @param isSet * 설정여부 */ public static void setKeepScreenOn(Context context, boolean isSet) { if (isSet) { ((Activity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { ((Activity) context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } /** * 키패드 표시하기 * * @since 1.0.0 * @param context * @param view */ public static void showSoftInput(Context context, EditText view) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } /** * 키패드 숨기기 * * @since 1.0.0 * @param context * @param view */ public static void hideSoftInput(Context context, EditText view) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } /** * 네트워크 상태 확인하기 * * @since 1.0.0 * @param context * @return boolean */ public static boolean isNetworkAvailbe(Context context) { boolean isNetworkAvailbe = false; ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { isNetworkAvailbe = true; } return isNetworkAvailbe; } /** * 패키지 설치 요청하기 * * @since 1.0.0 * @param context * 액티비티의 컨텍스트 * @param apkUri * 패키지 파일 경로 */ public static void installPackage(Context context, Uri apkUri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); ((Activity) context).startActivity(intent); } /** * 패키지 삭제 요청하기 * * @since 1.0.0 * @param context * 액티비티의 컨텍스트 * @param packageName * 패키지명 */ public static void uninstallPackage(Context context, String packageName) { Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts("package", packageName, null)); ((Activity) context).startActivity(intent); } /** * 바로가기 생성하기 * * @since 1.0.0 * @param context * @param packageName * @param className * @param displayName * @param icon * @param flags * @param category * @param extraBundle */ public static void createShortCut(Context context, String packageName, String className, String displayName, Bitmap icon, int flags, String category, Bundle extras) { assert null != context && null != packageName && null != className && null != displayName; Intent shortcutIntent = new Intent(); shortcutIntent.setClassName(packageName, className); shortcutIntent.addFlags(flags); if (null != extras) { shortcutIntent.putExtras(extras); } // example.. // shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // shortcutIntent.addCategory(Intent.ACTION_PICK_ACTIVITY); Intent intent = new Intent(); intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, displayName); if (null != icon) { intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon); } intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); context.sendBroadcast(intent); } /** * 파일복사 * * @since 1.0.0 * @param sourceFile * 원본파일 * @param destFile * 타겟파일 * @throws IOException */ @SuppressWarnings("resource") public static void copyFile(File sourceFile, File destFile) throws IOException { if (!destFile.exists()) { destFile.createNewFile(); } FileChannel source = null; FileChannel destination = null; try { source = new FileInputStream(sourceFile).getChannel(); destination = new FileOutputStream(destFile).getChannel(); long count = 0; long size = sourceFile.length(); if (size < 4194304) // 1024 * 1024 * 4 bytes : 4MB { // small file.. MappedByteBuffer mbuf = source.map(FileChannel.MapMode.READ_ONLY, 0, sourceFile.length()); destination.write(mbuf); } else { // large file.. while ((count += destination.transferFrom(source, count, size - count)) < size) { ; // copy loop } } } finally { if (source != null) { source.close(); } if (destination != null) { destination.close(); } } } /** * 뷰 투명처리 * * @since 1.0.0 * @param view * @param transparent */ public static void transparent(View view, boolean transparent) { float alpha = 1; if (transparent) { alpha = 0.5f; } alpha(view, alpha); } /** * 뷰 알파값 적용 * * @since 1.0.0 * @param view * @param alpha */ public static void alpha(View view, float alpha) { if (1 == alpha) { view.clearAnimation(); } else { view.startAnimation(Animationz.alpha(null, alpha, alpha, 0, 0, true)); } } /** * Workaround for bug pre-Froyo, see here for more info: * http://android-developers.blogspot.com/2011/09/androids-http-clients.html */ public static void disableConnectionReuseIfNecessary() { // HTTP connection reuse which was buggy pre-froyo if (hasHttpConnectionBug()) { System.setProperty("http.keepAlive", "false"); } } /** * Get the size in bytes of a bitmap. * * @param bitmap * @return size in bytes */ @SuppressLint("NewApi") public static int getBitmapSize(Bitmap bitmap) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { return bitmap.getByteCount(); } // Pre HC-MR1 return bitmap.getRowBytes() * bitmap.getHeight(); } /** * Check if external storage is built-in or removable. * * @return True if external storage is removable (like an SD card), false * otherwise. */ @SuppressLint("NewApi") public static boolean isExternalStorageRemovable() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { return Environment.isExternalStorageRemovable(); } return true; } /** * Get the external app cache directory. * * @param context * The context to use * @return The external cache dir */ @SuppressLint("NewApi") public static File getExternalCacheDir(Context context) { if (hasExternalCacheDir()) { return context.getExternalCacheDir(); } // Before Froyo we need to construct the external cache dir ourselves final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/"; return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir); } /** * Check how much usable space is available at a given path. * * @param path * The path to check * @return The space available in bytes */ @SuppressLint("NewApi") public static long getUsableSpace(File path) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { return path.getUsableSpace(); } final StatFs stats = new StatFs(path.getPath()); return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks(); } /** * Get the memory class of this device (approx. per-app memory limit) * * @param context * @return */ public static int getMemoryClass(Context context) { return ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); } /** * Check if OS version has a http URLConnection bug. See here for more information: * http://android-developers.blogspot.com/2011/09/androids-http-clients.html * * @return */ public static boolean hasHttpConnectionBug() { return Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO; } /** * Check if OS version has built-in external cache dir method. * * @return */ public static boolean hasExternalCacheDir() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; } /** * Check if ActionBar is available. * * @return */ public static boolean hasActionBar() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; } /** * 비트맵 가져오기 * * @since 1.0.0 * @param url * @return bitmap * @throws MalformedURLException * , IOException, OutOfMemoryError */ public static Bitmap getBitmapFromUrl(String url) throws MalformedURLException, IOException, OutOfMemoryError { Bitmap bm = null; URL aURL = new URL(url); URLConnection conn = aURL.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); bm = BitmapFactory.decodeStream(new FlushedInputStream(is)); bis.close(); is.close(); return bm; } /** * * <h3><b>FlushedInputStream</b></h3></br> * * @author aincc@barusoft.com * @version 1.0.0 * @since 1.0.0 */ static class FlushedInputStream extends FilterInputStream { public FlushedInputStream(InputStream inputStream) { super(inputStream); } @Override public long skip(long n) throws IOException { long totalBytesSkipped = 0L; while (totalBytesSkipped < n) { long bytesSkipped = in.skip(n - totalBytesSkipped); if (bytesSkipped == 0L) { int b = read(); if (b < 0) { break; // we reached EOF } else { bytesSkipped = 1; // we read one byte } } totalBytesSkipped += bytesSkipped; } return totalBytesSkipped; } } /** * * @since 1.0.0 * @param bitmap * @param roundPx * @param roundPy * @return rounded corner bitmap * @throws OutOfMemoryError */ public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx, float roundPy) throws OutOfMemoryError { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPy, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * 비트맵 이미지 리사이즈하기.<br> * * @since 1.0.0 * @param source * @param maxResolution * @return resized bitmap * @throws OutOfMemoryError */ public static Bitmap resizeBitmapImage(Bitmap source, int maxResolution) throws OutOfMemoryError { Bitmap resizeBitmap = null; int width = source.getWidth(); int height = source.getHeight(); int newWidth = width; int newHeight = height; float rate = 0.0f; if (width > height) { if (maxResolution < width) { rate = maxResolution / (float) width; newHeight = (int) (height * rate); newWidth = maxResolution; } } else { if (maxResolution < height) { rate = maxResolution / (float) height; newWidth = (int) (width * rate); newHeight = maxResolution; } } resizeBitmap = Bitmap.createScaledBitmap(source, newWidth, newHeight, true); return resizeBitmap; } /** * * @since 1.0.0 * @param context * @param imageView * @param bitmap */ public static void displayImage(Context context, final ImageView imageView, final Bitmap bitmap) { ((Activity) context).runOnUiThread(new Runnable() { @Override public void run() { if (null != bitmap && null != imageView) { imageView.setImageBitmap(bitmap); } } }); } /** * * @since 1.0.0 * @param options * @param reqWidth * @param reqHeight * @return */ public 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) { if (width > height) { inSampleSize = Math.round((float) height / (float) reqHeight); } else { inSampleSize = Math.round((float) width / (float) reqWidth); } } return inSampleSize; } /** * * @since 1.0.0 * @param res * @param resId * @param reqWidth * @param reqHeight * @return */ public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } /** * 뷰의 스크린샷 생성 * * @since 1.0.0 * @param view * @return bitmap */ public static Bitmap takeScreenShot(View view) { if (null == view) { return null; } assert view.getWidth() > 0 && view.getHeight() > 0; Bitmap.Config config = Bitmap.Config.ARGB_8888; Bitmap bitmap = null; try { bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), config); Canvas canvas = new Canvas(bitmap); view.draw(canvas); } catch (OutOfMemoryError e) { e.printStackTrace(); } return bitmap; } // ///////////////////////////////////////////////////////////////////////// // DEBUG Utils // ///////////////////////////////////////////////////////////////////////// /** * * @since 1.0.0 * @param clazz */ public static void logHeapMem(@SuppressWarnings("rawtypes") Class clazz) { Double allocated = new Double(Debug.getNativeHeapAllocatedSize()) / new Double((1048576)); Double available = new Double(Debug.getNativeHeapSize()) / 1048576.0; Double free = new Double(Debug.getNativeHeapFreeSize()) / 1048576.0; DecimalFormat df = new DecimalFormat(); df.setMaximumFractionDigits(2); df.setMinimumFractionDigits(2); Logger.i("debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free) in [" + clazz.getName() + "]"); Logger.i("debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory() / 1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory() / 1048576)) + "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory() / 1048576)) + "MB free)"); System.gc(); } // ///////////////////////////////////////////////////////////////////////// // String Utils // ///////////////////////////////////////////////////////////////////////// /** * UTF 코드로 출력하기 * * @since 1.0.0 * @param string * @return the UTF Code String */ public static String printUTFCodeString(String string) { StringBuilder sb = new StringBuilder(); for (int ii = 0; ii < string.length(); ii++) { sb.append(String.format("U+%04X ", string.codePointAt(ii))); } return sb.toString(); // string : "한" // 한글처리관련 // 정준분해 : 소리 마디를 첫가끝 코드로 분해 // ㅎㅏㄴ // U+1112 U+1161 U+11AB // String NFD = Normalizer.normalize(string, Normalizer.Form.NFD); // 정준분해한 뒤 다시 정준결합 : 첫가끝 코드를 소리마디로 결합 // 한 // U+D55C // String NFC = Normalizer.normalize(string, Normalizer.Form.NFC); } /** * Hex 코드로 출력하기 * * @since 1.0.0 * @param string * @return the Hex Code String */ public static String printHexCodeString(String string) { StringBuilder sb = new StringBuilder(); byte[] bytes = string.getBytes(); for (byte b : bytes) { sb.append(String.format("0x%02X ", b)); } return sb.toString(); } /** * 널체크 * * @param str * @return boolean */ public static boolean isNull(CharSequence str) { if (null == str) return true; return false; } /** * 빈문자열 체크 * * @param str * @return boolean */ public static boolean isEmpty(CharSequence str) { if (isNull(str)) return true; if (str.length() <= 0) return true; return false; } /** * 문자열 바이트 크기 가져오기 * * @since 1.0.0 * @param data * @return */ public static int getByteSize(String data) { return getByteSize(data, (char) 0); } /** * 숫자로 구성된 문자열 체크 * * @param data * @return boolean */ public static boolean isDigit(String data) { if (data == null || data.length() <= 0) return false; for (int i = 0; i < data.length(); i++) { if (data.charAt(i) >= '0' && data.charAt(i) <= '9') continue; else return false; } return true; } /** * 숫자로 구성된 문자열 체크 (except 문자를 "" 으로 치환) * * @param data * @param except * @return boolean */ public static boolean isDigit(String data, String except) { data = data.replace(except, ""); return isDigit(data); } /** * 트림처리후 빈문자열 체크 * * @param str * @return boolean */ public static boolean isTrimEmpty(String str) { if (isNull(str)) { return true; } if (str.trim().length() <= 0) { return true; } return false; } /** * 문자열 바이트크기 가져오기 * * @param data * @param except * @return byte size */ public static int getByteSize(String data, char except) { int size = 0; for (int i = 0; i < data.length(); i++) { if (except != 0 && data.charAt(i) == except) continue; if (data.charAt(i) > 127) size += 2; else size++; } return size; } /** * 문자열에서 콤마 제거하기 * * @param data * @return */ public static String removeComma(CharSequence data) { return removeComma(data.toString()); } /** * 문자열에서 콤마 제거하기 * * @since 1.0.0 * @param data * @return */ public static String removeComma(String data) { if (data == null || data.equals("")) { return ""; } return (data.replace(",", "")).replace(" ", "").trim(); } /** * 문자열 숫자 비교 * * @param source * @param target * @return */ public static int compareDigit(String source, String target) { String src = source.replace(",", "").trim(); String tar = target.replace(",", "").trim(); if (src.length() > tar.length()) { return 1; } else if (src.length() < tar.length()) { return -1; } else { return src.compareTo(tar); } } /** * 바이트배열을 헥사문자열로 변환하기 * * @author aincc@barusoft.com * @param arr * @return */ public static String getByteArrayToHexString(byte[] arr) { String hex = ""; String _tmp = ""; String div = " "; for (int i = 0; i < arr.length; i++) { _tmp = Integer.toHexString(arr[i] & 0xff).toUpperCase(); if (_tmp.length() == 1) _tmp = "0" + _tmp; hex += "0x" + _tmp; if (i < arr.length - 1) hex += div; } return hex; } /** * 바이트배열을 헥사문자열로 변환하기 * * @author aincc@barusoft.com * @param arr * @return */ public static String getByteArrayToHexStringNo0x(byte[] arr) { String hex = ""; String _tmp = ""; String div = ""; for (int i = 0; i < arr.length; i++) { _tmp = Integer.toHexString(arr[i] & 0xff).toUpperCase(); if (_tmp.length() == 1) _tmp = "0" + _tmp; hex += "" + _tmp; if (i < arr.length - 1) hex += div; } return hex; } /** * 정의한 문자만 인코딩 * * @since 1.0.0 * @param source * @return */ public static String encodedURI(String source) { String[] findList = { "#", "+", "&", "%", " " }; String[] replList = { "%23", "%2B", "%26", "%25", "%20" }; return StringUtils.replaceEach(source, findList, replList); } // ///////////////////////////////////////////////////////////////////////// // UI Utils // ///////////////////////////////////////////////////////////////////////// private static Handler shared_handler = null; /** * * @since 1.0.0 * @return shared_handler */ public static Handler getHandler() { return shared_handler; } /** * UI Thread 체크 * * @since 1.0.0 * @return boolean */ public static boolean isUIThread() { long uiId = Looper.getMainLooper().getThread().getId(); long cId = Thread.currentThread().getId(); return uiId == cId; } /** * * @since 1.0.0 * @return boolean */ public static boolean isMainThread() { return Looper.myLooper() == Looper.getMainLooper(); } /** * * @since 1.0.0 */ public static void assertInMainThread() { if (!isMainThread()) { throw new RuntimeException("Main thread assertion failed"); } } /** * * @since 1.0.0 * @param call * @return * @throws Exception */ public static <T> T callInMainThread(Callable<T> call) throws Exception { if (isMainThread()) { return call.call(); } else { FutureTask<T> task = new FutureTask<T>(call); getHandler().post(task); return task.get(); } } /** * 이미지뷰에서 비트맵 가져오기 * * @since 1.0.0 * @param view * @return bitmap */ public static Bitmap getImage(ImageView view) { if (((ImageView) view).getDrawable() != null) { return ((BitmapDrawable) (((ImageView) view).getDrawable())).getBitmap(); } return null; } // ///////////////////////////////////////////////////////////////////////// // IO Utils // ///////////////////////////////////////////////////////////////////////// public static final byte[] EMPTY_BYTES = new byte[0]; /** * @since 1.0.0 * @param closeable */ public static void close(Closeable closeable) { try { if (closeable != null) { closeable.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * @since 1.0.0 * @param input * @return byte[] */ public static byte[] readData(InputStream input) { if (input == null) { return null; } ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len = -1; try { while ((len = input.read(buf)) != -1) { output.write(buf, 0, len); } return output.toByteArray(); } catch (IOException e) { e.printStackTrace(); return null; } finally { close(input); } } /** * * @since 1.0.0 * @param input * @return String */ public static String readString(InputStream input) { if (input == null) { return null; } return readString(new InputStreamReader(input, Charsets.UTF_8)); } /** * * @since 1.0.0 * @param reader * @return String */ public static String readString(Reader reader) { if (reader == null) { return null; } StringBuilder builder = new StringBuilder(); char[] buf = new char[1024]; int len = -1; try { while ((len = reader.read(buf)) != -1) { builder.append(buf, 0, len); } return builder.toString(); } catch (IOException e) { e.printStackTrace(); return null; } finally { close(reader); } } /** * * @since 1.0.0 * @param input * @return Bitmap */ public static Bitmap readBitmap(InputStream input) { if (input == null) return null; try { return BitmapFactory.decodeStream(input); } catch (Exception e) { e.printStackTrace(); return null; } finally { close(input); } } // ///////////////////////////////////////////////////////////////////////// // Memory Utils // ///////////////////////////////////////////////////////////////////////// /** * * @since 1.0.0 * @param view */ public static void recycleImageView(ImageView view) { if (((ImageView) view).getDrawable() != null) { ((BitmapDrawable) (((ImageView) view).getDrawable())).getBitmap().recycle(); } ((ImageView) view).setImageDrawable(null); } /** * 뷰에 할당된 이미지를 모두 해제한다. * * @since 1.0.0 * @param view */ public static void unbindDrawables(View view) { if (null != view.getBackground()) { view.getBackground().setCallback(null); } if (view instanceof ImageView) { if (((ImageView) view).getDrawable() != null) { ((BitmapDrawable) (((ImageView) view).getDrawable())).getBitmap().recycle(); } ((ImageView) view).setImageDrawable(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } } }