migration to Kotlin (WIP)

This commit is contained in:
Thibault Deckers 2020-09-29 20:00:00 +09:00
parent bdd18d9e71
commit b315ebe724
6 changed files with 106 additions and 152 deletions

View file

@ -1,79 +0,0 @@
package deckers.thibault.aves.utils;
import androidx.annotation.Nullable;
import androidx.exifinterface.media.ExifInterface;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MetadataHelper {
// interpret EXIF code to angle (0, 90, 180 or 270 degrees)
public static int getOrientationDegreesForExifCode(int exifOrientation) {
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_180: // bottom, right side
return 180;
case ExifInterface.ORIENTATION_ROTATE_90: // right side, top
return 90;
case ExifInterface.ORIENTATION_ROTATE_270: // left side, bottom
return 270;
}
// all other orientations (regular, flipped...) default to an angle of 0 degree
return 0;
}
// yyyyMMddTHHmmss(.sss)?(Z|+/-hhmm)?
public static long parseVideoMetadataDate(@Nullable String dateString) {
if (dateString == null) {
return 0;
}
// optional sub-second
String subSecond = null;
Matcher subSecondMatcher = Pattern.compile("(\\d{6})(\\.\\d+)").matcher(dateString);
if (subSecondMatcher.find()) {
subSecond = subSecondMatcher.group(2).substring(1);
dateString = subSecondMatcher.replaceAll("$1");
}
// optional time zone
TimeZone timeZone = null;
Matcher timeZoneMatcher = Pattern.compile("(Z|[+-]\\d{4})$").matcher(dateString);
if (timeZoneMatcher.find()) {
timeZone = TimeZone.getTimeZone("GMT" + timeZoneMatcher.group().replaceAll("Z", ""));
dateString = timeZoneMatcher.replaceAll("");
}
Date date = null;
try {
DateFormat parser = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.US);
parser.setTimeZone((timeZone != null) ? timeZone : TimeZone.getTimeZone("GMT"));
date = parser.parse(dateString);
} catch (ParseException e) {
// ignore
}
if (date == null) {
return 0;
}
long dateMillis = date.getTime();
if (subSecond != null) {
try {
int millis = (int) (Double.parseDouble("." + subSecond) * 1000);
if (millis >= 0 && millis < 1000) {
dateMillis += millis;
}
} catch (NumberFormatException e) {
// ignore
}
}
return dateMillis;
}
}

View file

@ -1,19 +0,0 @@
package deckers.thibault.aves.utils;
public class MimeTypes {
public static final String IMAGE = "image";
public static final String DNG = "image/x-adobe-dng"; // .dng
public static final String GIF = "image/gif";
public static final String HEIC = "image/heic";
public static final String HEIF = "image/heif";
public static final String JPEG = "image/jpeg";
public static final String PNG = "image/png";
public static final String PSD = "image/x-photoshop"; // .psd
public static final String SVG = "image/svg+xml"; // .svg
public static final String WEBP = "image/webp";
public static final String VIDEO = "video";
public static final String AVI = "video/avi";
public static final String MP2T = "video/mp2t"; // .m2ts
public static final String MP4 = "video/mp4";
}

View file

@ -1,54 +0,0 @@
package deckers.thibault.aves.utils;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.regex.Pattern;
public class Utils {
private static final int logTagMaxLength = 23;
private static final Pattern logTagPackagePattern = Pattern.compile("(\\w)(\\w*)\\.");
public static String createLogTag(Class<?> clazz) {
// shorten class name to "a.b.CccDdd"
String logTag = logTagPackagePattern.matcher(clazz.getName()).replaceAll("$1.");
if (logTag.length() > logTagMaxLength) {
// shorten class name to "a.b.CD"
String simpleName = clazz.getSimpleName();
String shortSimpleName = simpleName.replaceAll("[a-z]", "");
logTag = logTag.replace(simpleName, shortSimpleName);
if (logTag.length() > logTagMaxLength) {
// shorten class name to "CD"
logTag = shortSimpleName;
}
}
return logTag;
}
public static void copyFile(final File source, final FileDescriptor descriptor) throws IOException {
try (FileInputStream inStream = new FileInputStream(source); FileOutputStream outStream = new FileOutputStream(descriptor)) {
final FileChannel inChannel = inStream.getChannel();
final FileChannel outChannel = outStream.getChannel();
final long size = inChannel.size();
long position = 0;
while (position < size) {
position += inChannel.transferTo(position, 1024L * 1024L, outChannel);
}
}
}
public static void copyFile(final File source, final File destination) throws IOException {
try (FileInputStream inStream = new FileInputStream(source); FileOutputStream outStream = new FileOutputStream(destination)) {
final FileChannel inChannel = inStream.getChannel();
final FileChannel outChannel = outStream.getChannel();
final long size = inChannel.size();
long position = 0;
while (position < size) {
position += inChannel.transferTo(position, 1024L * 1024L, outChannel);
}
}
}
}

View file

@ -0,0 +1,63 @@
package deckers.thibault.aves.utils
import androidx.exifinterface.media.ExifInterface
import java.text.DateFormat
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern
object MetadataHelper {
// interpret EXIF code to angle (0, 90, 180 or 270 degrees)
@JvmStatic
fun getOrientationDegreesForExifCode(exifOrientation: Int): Int = when (exifOrientation) {
ExifInterface.ORIENTATION_ROTATE_180 -> 180
ExifInterface.ORIENTATION_ROTATE_90 -> 90
ExifInterface.ORIENTATION_ROTATE_270 -> 270
else -> 0 // all other orientations (regular, flipped...) default to an angle of 0 degree
}
// yyyyMMddTHHmmss(.sss)?(Z|+/-hhmm)?
@JvmStatic
fun parseVideoMetadataDate(metadataDate: String?): Long {
var dateString = metadataDate ?: return 0
// optional sub-second
var subSecond: String? = null
val subSecondMatcher = Pattern.compile("(\\d{6})(\\.\\d+)").matcher(dateString)
if (subSecondMatcher.find()) {
subSecond = subSecondMatcher.group(2)?.substring(1)
dateString = subSecondMatcher.replaceAll("$1")
}
// optional time zone
var timeZone: TimeZone? = null
val timeZoneMatcher = Pattern.compile("(Z|[+-]\\d{4})$").matcher(dateString)
if (timeZoneMatcher.find()) {
timeZone = TimeZone.getTimeZone("GMT" + timeZoneMatcher.group().replace("Z".toRegex(), ""))
dateString = timeZoneMatcher.replaceAll("")
}
val date: Date = try {
val parser = SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.US)
parser.timeZone = timeZone ?: TimeZone.getTimeZone("GMT")
parser.parse(dateString)
} catch (e: ParseException) {
// ignore
null
} ?: return 0
var dateMillis = date.time
if (subSecond != null) {
try {
val millis = (".$subSecond".toDouble() * 1000).toInt()
if (millis in 0..999) {
dateMillis += millis.toLong()
}
} catch (e: NumberFormatException) {
// ignore
}
}
return dateMillis
}
}

View file

@ -0,0 +1,18 @@
package deckers.thibault.aves.utils
object MimeTypes {
const val IMAGE = "image"
const val DNG = "image/x-adobe-dng" // .dng
const val GIF = "image/gif"
const val HEIC = "image/heic"
const val HEIF = "image/heif"
const val JPEG = "image/jpeg"
const val PNG = "image/png"
const val PSD = "image/x-photoshop" // .psd
const val SVG = "image/svg+xml" // .svg
const val WEBP = "image/webp"
const val VIDEO = "video"
const val AVI = "video/avi"
const val MP2T = "video/mp2t" // .m2ts
const val MP4 = "video/mp4"
}

View file

@ -0,0 +1,25 @@
package deckers.thibault.aves.utils
import java.util.regex.Pattern
object Utils {
private const val LOG_TAG_MAX_LENGTH = 23
private val LOG_TAG_PACKAGE_PATTERN = Pattern.compile("(\\w)(\\w*)\\.")
@JvmStatic
fun createLogTag(clazz: Class<*>): String {
// shorten class name to "a.b.CccDdd"
var logTag = LOG_TAG_PACKAGE_PATTERN.matcher(clazz.name).replaceAll("$1.")
if (logTag.length > LOG_TAG_MAX_LENGTH) {
// shorten class name to "a.b.CD"
val simpleName = clazz.simpleName
val shortSimpleName = simpleName.replace("[a-z]".toRegex(), "")
logTag = logTag.replace(simpleName, shortSimpleName)
if (logTag.length > LOG_TAG_MAX_LENGTH) {
// shorten class name to "CD"
logTag = shortSimpleName
}
}
return logTag
}
}