package com.hpw.myapp.widget.imageselector.utils; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.media.ExifInterface; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.text.TextUtils; import java.io.Closeable; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; /* * Modified from original in AOSP. */ public class CropUtil { private static final String SCHEME_FILE = "file"; private static final String SCHEME_CONTENT = "content"; public static void closeSilently(@Nullable Closeable c) { if (c == null) return; try { c.close(); } catch (Throwable t) { // Do nothing } } public static int getExifRotation(File imageFile) { if (imageFile == null) return 0; try { ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath()); // We only recognize a subset of orientation tag values switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) { case ExifInterface.ORIENTATION_ROTATE_90: return 90; case ExifInterface.ORIENTATION_ROTATE_180: return 180; case ExifInterface.ORIENTATION_ROTATE_270: return 270; default: return ExifInterface.ORIENTATION_UNDEFINED; } } catch (IOException e) { return 0; } } public static boolean copyExifRotation(File sourceFile, File destFile) { if (sourceFile == null || destFile == null) return false; try { ExifInterface exifSource = new ExifInterface(sourceFile.getAbsolutePath()); ExifInterface exifDest = new ExifInterface(destFile.getAbsolutePath()); exifDest.setAttribute(ExifInterface.TAG_ORIENTATION, exifSource.getAttribute(ExifInterface.TAG_ORIENTATION)); exifDest.saveAttributes(); return true; } catch (IOException e) { return false; } } @Nullable public static File getFromMediaUri(Context context, ContentResolver resolver, Uri uri) { if (uri == null) return null; if (SCHEME_FILE.equals(uri.getScheme())) { return new File(uri.getPath()); } else if (SCHEME_CONTENT.equals(uri.getScheme())) { final String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME}; Cursor cursor = null; try { cursor = resolver.query(uri, filePathColumn, null, null, null); if (cursor != null && cursor.moveToFirst()) { final int columnIndex = (uri.toString().startsWith("content://com.google.android.gallery3d")) ? cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) : cursor.getColumnIndex(MediaStore.MediaColumns.DATA); // Picasa images on API 13+ if (columnIndex != -1) { String filePath = cursor.getString(columnIndex); if (!TextUtils.isEmpty(filePath)) { return new File(filePath); } } } } catch (IllegalArgumentException e) { // Google Drive images return getFromMediaUriPfd(context, resolver, uri); } catch (SecurityException ignored) { // Nothing we can do } finally { if (cursor != null) cursor.close(); } } return null; } private static String getTempFilename(Context context) throws IOException { File outputDir = context.getCacheDir(); File outputFile = File.createTempFile("image", "tmp", outputDir); return outputFile.getAbsolutePath(); } @Nullable private static File getFromMediaUriPfd(Context context, ContentResolver resolver, Uri uri) { if (uri == null) return null; FileInputStream input = null; FileOutputStream output = null; try { ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r"); FileDescriptor fd = pfd.getFileDescriptor(); input = new FileInputStream(fd); String tempFilename = getTempFilename(context); output = new FileOutputStream(tempFilename); int read; byte[] bytes = new byte[4096]; while ((read = input.read(bytes)) != -1) { output.write(bytes, 0, read); } return new File(tempFilename); } catch (IOException ignored) { // Nothing we can do } finally { closeSilently(input); closeSilently(output); } return null; } // public static void startBackgroundJob(MonitoredActivity activity, // String title, String message, Runnable job, Handler handler) { // // Make the progress dialog uncancelable, so that we can guarantee // // the thread will be done before the activity getting destroyed // ProgressDialog dialog = ProgressDialog.show( // activity, title, message, true, false); // new Thread(new BackgroundJob(activity, job, dialog, handler)).start(); // } // private static class BackgroundJob extends MonitoredActivity.LifeCycleAdapter implements Runnable { // // private final MonitoredActivity activity; // private final ProgressDialog dialog; // private final Runnable job; // private final Handler handler; // private final Runnable cleanupRunner = new Runnable() { // public void run() { // activity.removeLifeCycleListener(BackgroundJob.this); // if (dialog.getWindow() != null) dialog.dismiss(); // } // }; // // public BackgroundJob(MonitoredActivity activity, Runnable job, // ProgressDialog dialog, Handler handler) { // this.activity = activity; // this.dialog = dialog; // this.job = job; // this.activity.addLifeCycleListener(this); // this.handler = handler; // } // // public void run() { // try { // job.run(); // } finally { // handler.post(cleanupRunner); // } // } // // @Override // public void onActivityDestroyed(MonitoredActivity activity) { // // We get here only when the onDestroyed being called before // // the cleanupRunner. So, run it now and remove it from the queue // cleanupRunner.run(); // handler.removeCallbacks(cleanupRunner); // } // // @Override // public void onActivityStopped(MonitoredActivity activity) { // dialog.hide(); // } // // @Override // public void onActivityStarted(MonitoredActivity activity) { // dialog.show(); // } // } }