diff --git a/app/src/org/commcare/utils/FileUtil.java b/app/src/org/commcare/utils/FileUtil.java index e26b9c90c..a65c33b5f 100644 --- a/app/src/org/commcare/utils/FileUtil.java +++ b/app/src/org/commcare/utils/FileUtil.java @@ -121,7 +121,7 @@ public static boolean cleanFilePath(String fullPath, String extendedPath) { private static final String illegalChars = "'*','+'~|<> !?:./\\"; - public static String SanitizeFileName(String input) { + public static String sanitizeFileName(String input) { for (char c : illegalChars.toCharArray()) { input = input.replace(c, '_'); } @@ -356,18 +356,17 @@ public static String getGlobalStringUri(String fileLocation) { return "file://" + fileLocation; } - public static void checkReferenceURI(Resource r, String URI, Vector problems) throws InvalidReferenceException { - Reference mRef = ReferenceManager.instance().DeriveReference(URI); + public static Reference checkReferenceUri(String uri) throws InvalidReferenceException { + Reference mRef = ReferenceManager.instance().DeriveReference(uri); String mLocalReference = mRef.getLocalURI(); try { if (!mRef.doesBinaryExist()) { - problems.addElement(new MissingMediaException(r, "Missing external media: " + mLocalReference, URI, - MissingMediaException.MissingMediaExceptionType.FILE_NOT_FOUND)); + throw new InvalidReferenceException("Missing external media: " + mLocalReference); } } catch (IOException e) { - problems.addElement(new MissingMediaException(r, "Problem reading external media: " + mLocalReference, URI, - MissingMediaException.MissingMediaExceptionType.FILE_NOT_ACCESSIBLE)); + throw new InvalidReferenceException("Problem reading external media: " + mLocalReference); } + return mRef; } public static boolean referenceFileExists(String uri) { @@ -495,8 +494,9 @@ public static String getMd5Hash(File file) { BigInteger number = new BigInteger(1, messageDigest); String md5 = number.toString(16); - while (md5.length() < 32) + while (md5.length() < 32) { md5 = "0" + md5; + } is.close(); return md5; @@ -613,7 +613,8 @@ public static boolean scaleAndSaveImage(File originalImage, String finalFilePath Pair bitmapAndScaledBool = MediaUtil.inflateImageSafe(originalImage.getAbsolutePath()); if (bitmapAndScaledBool.second) { Logger.log(LogTypes.TYPE_FORM_ENTRY, - "An image captured during form entry was too large to be processed at its original size, and had to be downsized"); + "An image captured during form entry was too large to be processed at its original size, " + + "and had to be downsized"); } Bitmap scaledBitmap = getBitmapScaledByMaxDimen(bitmapAndScaledBool.first, maxDimen); if (scaledBitmap != null) { @@ -724,7 +725,9 @@ public static Uri getUriForExternalFile(Context context, File file) { * @param dstFile destination File where we need to copy the inputStream */ public static void copyFile(InputStream inputStream, File dstFile) throws IOException { - if (inputStream == null) return; + if (inputStream == null) { + return; + } OutputStream outputStream = new FileOutputStream(dstFile); StreamsUtil.writeFromInputToOutputUnmanaged(inputStream, outputStream); inputStream.close(); @@ -845,8 +848,13 @@ public static void addMediaToGallery(Context context, File file) throws } /** - * Returns true only when we're certain that the file size is too large. - *

https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo + * Checks if a file referenced by a content URI exceeds the maximum allowed upload size + *

+ * @param contentResolver ContentResolver to query the file size + * @param uri Content URI of the file to check + * @return true if the file size exceeds FormUploadUtil.MAX_BYTES, false otherwise or if size cannot be determined + * @see FormUploadUtil#MAX_BYTES + * @see Android docs */ public static boolean isFileTooLargeToUpload(ContentResolver contentResolver, Uri uri) { try (Cursor returnCursor = contentResolver.query(uri, null, null, null, null)) { @@ -864,30 +872,7 @@ public static void copyFileWithExifData(File sourceFile, File destFile) throws I copyFile(sourceFile, destFile); // Then copy EXIF data - ExifInterface sourceExif = new ExifInterface(sourceFile.getAbsolutePath()); - ExifInterface destExif = new ExifInterface(destFile.getAbsolutePath()); - - // Copy GPS data - String[] tagsToPreserve = { - ExifInterface.TAG_GPS_LATITUDE, - ExifInterface.TAG_GPS_LATITUDE_REF, - ExifInterface.TAG_GPS_LONGITUDE, - ExifInterface.TAG_GPS_LONGITUDE_REF, - ExifInterface.TAG_GPS_TIMESTAMP, - ExifInterface.TAG_GPS_DATESTAMP, - // Preserve other important EXIF data - ExifInterface.TAG_DATETIME, - ExifInterface.TAG_ORIENTATION - }; - - for (String tag : tagsToPreserve) { - String value = sourceExif.getAttribute(tag); - if (value != null) { - destExif.setAttribute(tag, value); - } - } - - destExif.saveAttributes(); + copyExifData(sourceFile.getAbsolutePath(), destFile.getAbsolutePath()); } public static boolean scaleAndSaveImageWithExif(File sourceFile, File destFile, int maxDimen) throws IOException { @@ -896,26 +881,40 @@ public static boolean scaleAndSaveImageWithExif(File sourceFile, File destFile, if (scaled) { // Copy EXIF data from source to scaled image - ExifInterface sourceExif = new ExifInterface(sourceFile.getAbsolutePath()); - ExifInterface destExif = new ExifInterface(destFile.getAbsolutePath()); - - // Copy GPS and other important EXIF data - copyExifData(sourceExif, destExif); - destExif.saveAttributes(); + copyExifData(sourceFile.getAbsolutePath(), destFile.getAbsolutePath()); } return scaled; } - private static void copyExifData(ExifInterface source, ExifInterface dest) { + private static void copyExifData(String sourcePath, String destPath) throws IOException { + ExifInterface source = new ExifInterface(sourcePath); + ExifInterface dest = new ExifInterface(destPath); + String[] tagsToPreserve = { + // GPS data ExifInterface.TAG_GPS_LATITUDE, ExifInterface.TAG_GPS_LATITUDE_REF, ExifInterface.TAG_GPS_LONGITUDE, ExifInterface.TAG_GPS_LONGITUDE_REF, ExifInterface.TAG_GPS_TIMESTAMP, ExifInterface.TAG_GPS_DATESTAMP, + ExifInterface.TAG_GPS_ALTITUDE, + ExifInterface.TAG_GPS_ALTITUDE_REF, + ExifInterface.TAG_GPS_AREA_INFORMATION, + + // Timestamp data ExifInterface.TAG_DATETIME, + ExifInterface.TAG_DATETIME_DIGITIZED, + ExifInterface.TAG_DATETIME_ORIGINAL, + ExifInterface.TAG_OFFSET_TIME, + ExifInterface.TAG_OFFSET_TIME_ORIGINAL, + ExifInterface.TAG_OFFSET_TIME_DIGITIZED, + + // Image metadata + ExifInterface.TAG_COPYRIGHT, + ExifInterface.TAG_IMAGE_DESCRIPTION, + ExifInterface.TAG_EXIF_VERSION, ExifInterface.TAG_ORIENTATION }; @@ -925,5 +924,7 @@ private static void copyExifData(ExifInterface source, ExifInterface dest) { dest.setAttribute(tag, value); } } + + dest.saveAttributes(); } }