diff --git a/androidutils/src/main/java/com/dhims/androidutils/ExifUtil.java b/androidutils/src/main/java/com/dhims/androidutils/ExifUtil.java new file mode 100644 index 0000000..3cb04a6 --- /dev/null +++ b/androidutils/src/main/java/com/dhims/androidutils/ExifUtil.java @@ -0,0 +1,111 @@ +package com.dhims.androidutils; + +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.os.Build; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Utility functions for handling Exif. + * + * @author Dhimant Desai (dhimant1990@gmail.com) + */ +public class ExifUtil { + + public static Bitmap rotateBitmap(String src, Bitmap bitmap) { + try { + int orientation = getExifOrientation(src); + + if (orientation == 1) { + return bitmap; + } + + Matrix matrix = new Matrix(); + switch (orientation) { + case 2: + matrix.setScale(-1, 1); + break; + case 3: + matrix.setRotate(180); + break; + case 4: + matrix.setRotate(180); + matrix.postScale(-1, 1); + break; + case 5: + matrix.setRotate(90); + matrix.postScale(-1, 1); + break; + case 6: + matrix.setRotate(90); + break; + case 7: + matrix.setRotate(-90); + matrix.postScale(-1, 1); + break; + case 8: + matrix.setRotate(-90); + break; + default: + return bitmap; + } + + try { + Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + bitmap.recycle(); + return oriented; + } catch (OutOfMemoryError e) { + e.printStackTrace(); + return bitmap; + } + } catch (IOException e) { + e.printStackTrace(); + } + + return bitmap; + } + + public static int getExifOrientation(String src) throws IOException { + int orientation = 1; + + try { + /** + * if your are targeting only api level >= 5 + * ExifInterface exif = new ExifInterface(src); + * orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); + */ + if (Build.VERSION.SDK_INT >= 5) { + Class exifClass = Class.forName("android.media.ExifInterface"); + Constructor exifConstructor = exifClass.getConstructor(new Class[]{String.class}); + Object exifInstance = exifConstructor.newInstance(new Object[]{src}); + Method getAttributeInt = exifClass.getMethod("getAttributeInt", new Class[]{String.class, int.class}); + Field tagOrientationField = exifClass.getField("TAG_ORIENTATION"); + String tagOrientation = (String) tagOrientationField.get(null); + orientation = (Integer) getAttributeInt.invoke(exifInstance, new Object[]{tagOrientation, 1}); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + + return orientation; + } +} diff --git a/androidutils/src/main/java/com/dhims/androidutils/PathUtil.java b/androidutils/src/main/java/com/dhims/androidutils/PathUtil.java new file mode 100644 index 0000000..7974b76 --- /dev/null +++ b/androidutils/src/main/java/com/dhims/androidutils/PathUtil.java @@ -0,0 +1,166 @@ +package com.dhims.androidutils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.support.v4.content.ContextCompat; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Utility functions for handling path. + * + * @author Dhimant Desai (dhimant1990@gmail.com) + */ +public class PathUtil { + /* + * Gets the file path of the given Uri. + */ + @SuppressLint("NewApi") + public static String getPath(Context context, Uri uri) throws URISyntaxException { + final boolean needToCheckUri = Build.VERSION.SDK_INT >= 19; + String selection = null; + String[] selectionArgs = null; + // Uri is different in versions after KITKAT (Android 4.4), we need to + // deal with different Uris. + if (needToCheckUri && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } else { + File[] files = ContextCompat.getExternalFilesDirs(context, null); + for (File file : files) { + if (file.getAbsolutePath().contains(type)) { + return file.getParentFile().getParentFile().getParentFile().getParentFile() + "/" + split[1]; + } + } + } + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + uri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("image".equals(type)) { + uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + selection = "_id=?"; + selectionArgs = new String[]{split[1]}; + } + } + if ("content".equalsIgnoreCase(uri.getScheme())) { + String[] projection = {MediaStore.Images.Media.DATA}; + Cursor cursor = null; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + assert cursor != null; + int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + if (cursor.moveToFirst()) { + return cursor.getString(column_index); + } + } catch (Exception e) { + } + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + return null; + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + private static String getAppExternalDataDirectoryPath() { + StringBuilder sb = new StringBuilder(); + sb.append(Environment.getExternalStorageDirectory()) + .append(File.separator) + .append("Android") + .append(File.separator) + .append("data") + .append(File.separator) + .append("Package") + .append(File.separator); + + return sb.toString(); + } + + private static File getAppExternalDataDirectoryFile() { + File dataDirectoryFile = new File(getAppExternalDataDirectoryPath()); + dataDirectoryFile.mkdirs(); + + return dataDirectoryFile; + } + + public static File getTemporaryCameraFile() { + File storageDir = new File(getAppExternalDataDirectoryFile(), "Camera"); + storageDir.mkdirs(); + File file = new File(storageDir, "CAMERA_" + System.currentTimeMillis() + ".jpg"); + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + return file; + } + + /** + * @return Last Capture Camera Image Path + */ + public static File getLastUsedCameraFile() { + File dataDir = new File(getAppExternalDataDirectoryFile(), "Camera"); + File[] files = dataDir.listFiles(); + List filteredFiles = new ArrayList<>(); + for (File file : files) { + if (file.getName().startsWith("CAMERA_")) { + filteredFiles.add(file); + } + } + + Collections.sort(filteredFiles); + if (!filteredFiles.isEmpty()) { + return filteredFiles.get(filteredFiles.size() - 1); + } else { + return null; + } + } +} \ No newline at end of file diff --git a/androidutils/src/main/java/com/dhims/androidutils/PermissionUtils.java b/androidutils/src/main/java/com/dhims/androidutils/PermissionUtils.java new file mode 100644 index 0000000..5113c05 --- /dev/null +++ b/androidutils/src/main/java/com/dhims/androidutils/PermissionUtils.java @@ -0,0 +1,79 @@ +package com.dhims.androidutils; + +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.preference.PreferenceManager; +import android.provider.Settings; +import android.support.v4.app.Fragment; + +/** + * Utility functions for handling Permission. + * + * @author Dhimant Desai (dhimant1990@gmail.com) + */ +public class PermissionUtils { + + public static boolean useRunTimePermissions() { + return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; + } + + public static boolean hasPermission(Activity activity, String permission) { + if (useRunTimePermissions()) { + return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; + } + return true; + } + + public static void requestPermissions(Activity activity, String[] permission, int requestCode) { + if (useRunTimePermissions()) { + activity.requestPermissions(permission, requestCode); + } + } + + public static void requestPermissions(Fragment fragment, String[] permission, int requestCode) { + if (useRunTimePermissions()) { + fragment.requestPermissions(permission, requestCode); + } + } + + public static boolean shouldShowRational(Activity activity, String permission) { + if (useRunTimePermissions()) { + return activity.shouldShowRequestPermissionRationale(permission); + } + return false; + } + + public static boolean shouldAskForPermission(Activity activity, String permission) { + if (useRunTimePermissions()) { + return !hasPermission(activity, permission) && + (!hasAskedForPermission(activity, permission) || + shouldShowRational(activity, permission)); + } + return false; + } + + public static void goToAppSettings(Activity activity) { + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.fromParts("package", activity.getPackageName(), null)); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + activity.startActivity(intent); + } + + public static boolean hasAskedForPermission(Activity activity, String permission) { + return PreferenceManager + .getDefaultSharedPreferences(activity) + .getBoolean(permission, false); + } + + public static void markedPermissionAsAsked(Activity activity, String permission) { + PreferenceManager + .getDefaultSharedPreferences(activity) + .edit() + .putBoolean(permission, true) + .apply(); + } +}