From 41a95885c105797b1ab0731374de013382fb96ab Mon Sep 17 00:00:00 2001 From: Ole-Morten Duesund Date: Fri, 27 Feb 2026 15:24:17 +0100 Subject: [PATCH] Remove dead code - Delete ExifWriter.kt (instantiated but never called) - Remove saveJpegFile() and unused imports from PhotoSaver - Remove CameraFlipButton() and unused imports from LensSwitcher - Remove companion object and unused imports from HapticFeedback - Remove getZoomPresets() from LensController - Update README to reflect ExifWriter removal and actual minSdk (35) Co-Authored-By: Claude Opus 4.6 --- README.md | 5 +- .../naiv/tiltshift/camera/LensController.kt | 7 -- .../no/naiv/tiltshift/storage/ExifWriter.kt | 96 ------------------- .../no/naiv/tiltshift/storage/PhotoSaver.kt | 62 ------------ .../java/no/naiv/tiltshift/ui/LensSwitcher.kt | 28 ------ .../no/naiv/tiltshift/util/HapticFeedback.kt | 11 --- 6 files changed, 2 insertions(+), 207 deletions(-) delete mode 100644 app/src/main/java/no/naiv/tiltshift/storage/ExifWriter.kt diff --git a/README.md b/README.md index 2fabd70..7668f6c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ A dedicated Android camera app for tilt-shift photography with real-time preview ## Requirements -- Android 8.0 (API 26) or higher +- Android 15 (API 35) or higher - Device with camera - OpenGL ES 2.0 support @@ -66,8 +66,7 @@ app/src/main/java/no/naiv/tiltshift/ │ ├── ZoomControl.kt # Zoom UI component │ └── LensSwitcher.kt # Lens selection UI ├── storage/ -│ ├── PhotoSaver.kt # MediaStore integration -│ └── ExifWriter.kt # EXIF metadata handling +│ └── PhotoSaver.kt # MediaStore integration & EXIF handling └── util/ ├── OrientationDetector.kt ├── LocationProvider.kt diff --git a/app/src/main/java/no/naiv/tiltshift/camera/LensController.kt b/app/src/main/java/no/naiv/tiltshift/camera/LensController.kt index 1939561..7fb7edc 100644 --- a/app/src/main/java/no/naiv/tiltshift/camera/LensController.kt +++ b/app/src/main/java/no/naiv/tiltshift/camera/LensController.kt @@ -88,11 +88,4 @@ class LensController { return availableLenses[currentLensIndex] } - /** - * Common zoom levels that can be achieved through digital zoom. - * These are presented as quick-select buttons. - */ - fun getZoomPresets(): List { - return listOf(0.5f, 1.0f, 2.0f, 5.0f) - } } diff --git a/app/src/main/java/no/naiv/tiltshift/storage/ExifWriter.kt b/app/src/main/java/no/naiv/tiltshift/storage/ExifWriter.kt deleted file mode 100644 index 4a7431a..0000000 --- a/app/src/main/java/no/naiv/tiltshift/storage/ExifWriter.kt +++ /dev/null @@ -1,96 +0,0 @@ -package no.naiv.tiltshift.storage - -import android.location.Location -import androidx.exifinterface.media.ExifInterface -import java.io.File -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale - -/** - * Writes EXIF metadata to captured images. - */ -class ExifWriter { - - private val dateTimeFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.US) - - /** - * Writes EXIF data to the specified image file. - */ - fun writeExifData( - file: File, - orientation: Int, - location: Location?, - make: String = "Android", - model: String = android.os.Build.MODEL - ) { - try { - val exif = ExifInterface(file) - - // Orientation - exif.setAttribute(ExifInterface.TAG_ORIENTATION, orientation.toString()) - - // Date/time - val dateTime = dateTimeFormat.format(Date()) - exif.setAttribute(ExifInterface.TAG_DATETIME, dateTime) - exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateTime) - exif.setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED, dateTime) - - // Camera info - exif.setAttribute(ExifInterface.TAG_MAKE, make) - exif.setAttribute(ExifInterface.TAG_MODEL, model) - exif.setAttribute(ExifInterface.TAG_SOFTWARE, "Tilt-Shift Camera") - - // GPS location - if (location != null) { - setLocationExif(exif, location) - } - - exif.saveAttributes() - } catch (e: Exception) { - e.printStackTrace() - } - } - - private fun setLocationExif(exif: ExifInterface, location: Location) { - // Latitude - val latitude = location.latitude - val latRef = if (latitude >= 0) "N" else "S" - exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, convertToDMS(Math.abs(latitude))) - exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, latRef) - - // Longitude - val longitude = location.longitude - val lonRef = if (longitude >= 0) "E" else "W" - exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, convertToDMS(Math.abs(longitude))) - exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, lonRef) - - // Altitude - if (location.hasAltitude()) { - val altitude = location.altitude - val altRef = if (altitude >= 0) "0" else "1" - exif.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, "${Math.abs(altitude).toLong()}/1") - exif.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, altRef) - } - - // Timestamp - val gpsTimeFormat = SimpleDateFormat("HH:mm:ss", Locale.US) - val gpsDateFormat = SimpleDateFormat("yyyy:MM:dd", Locale.US) - val timestamp = Date(location.time) - exif.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, gpsTimeFormat.format(timestamp)) - exif.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, gpsDateFormat.format(timestamp)) - } - - /** - * Converts decimal degrees to DMS (degrees/minutes/seconds) format for EXIF. - */ - private fun convertToDMS(coordinate: Double): String { - val degrees = coordinate.toInt() - val minutesDecimal = (coordinate - degrees) * 60 - val minutes = minutesDecimal.toInt() - val seconds = (minutesDecimal - minutes) * 60 - - // EXIF format: "degrees/1,minutes/1,seconds/1000" - return "$degrees/1,$minutes/1,${(seconds * 1000).toLong()}/1000" - } -} diff --git a/app/src/main/java/no/naiv/tiltshift/storage/PhotoSaver.kt b/app/src/main/java/no/naiv/tiltshift/storage/PhotoSaver.kt index 74ec8ea..e6d6ee5 100644 --- a/app/src/main/java/no/naiv/tiltshift/storage/PhotoSaver.kt +++ b/app/src/main/java/no/naiv/tiltshift/storage/PhotoSaver.kt @@ -3,9 +3,6 @@ package no.naiv.tiltshift.storage import android.content.ContentValues import android.content.Context import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.Canvas -import android.graphics.Paint import android.location.Location import android.net.Uri import android.os.Build @@ -15,8 +12,6 @@ import android.util.Log import androidx.exifinterface.media.ExifInterface import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import java.io.File -import java.io.FileOutputStream import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -38,8 +33,6 @@ class PhotoSaver(private val context: Context) { private const val TAG = "PhotoSaver" } - private val exifWriter = ExifWriter() - private val fileNameFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US) /** @@ -97,61 +90,6 @@ class PhotoSaver(private val context: Context) { } } - /** - * Saves a JPEG file (from CameraX ImageCapture) to the gallery. - */ - suspend fun saveJpegFile( - sourceFile: File, - orientation: Int, - location: Location? - ): SaveResult = withContext(Dispatchers.IO) { - try { - val fileName = "TILTSHIFT_${fileNameFormat.format(Date())}.jpg" - - val contentValues = ContentValues().apply { - put(MediaStore.Images.Media.DISPLAY_NAME, fileName) - put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") - put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000) - put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/TiltShift") - put(MediaStore.Images.Media.IS_PENDING, 1) - } - } - - val contentResolver = context.contentResolver - val uri = contentResolver.insert( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - contentValues - ) ?: return@withContext SaveResult.Error("Failed to create MediaStore entry") - - // Copy file to MediaStore - contentResolver.openOutputStream(uri)?.use { outputStream -> - sourceFile.inputStream().use { inputStream -> - inputStream.copyTo(outputStream) - } - } ?: return@withContext SaveResult.Error("Failed to open output stream") - - // Write EXIF data - writeExifToUri(uri, orientation, location) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - contentValues.clear() - contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) - contentResolver.update(uri, contentValues, null, null) - } - - // Clean up source file - sourceFile.delete() - - val path = getPathFromUri(uri) - SaveResult.Success(uri, path) - } catch (e: Exception) { - SaveResult.Error("Failed to save photo: ${e.message}", e) - } - } - private fun writeExifToUri(uri: Uri, orientation: Int, location: Location?) { try { context.contentResolver.openFileDescriptor(uri, "rw")?.use { pfd -> diff --git a/app/src/main/java/no/naiv/tiltshift/ui/LensSwitcher.kt b/app/src/main/java/no/naiv/tiltshift/ui/LensSwitcher.kt index d356512..c2ca806 100644 --- a/app/src/main/java/no/naiv/tiltshift/ui/LensSwitcher.kt +++ b/app/src/main/java/no/naiv/tiltshift/ui/LensSwitcher.kt @@ -9,9 +9,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CameraRear -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -90,28 +87,3 @@ private fun LensButton( ) } } - -/** - * Simple camera flip button (for future front camera support). - */ -@Composable -fun CameraFlipButton( - onClick: () -> Unit, - modifier: Modifier = Modifier -) { - Box( - modifier = modifier - .size(48.dp) - .clip(CircleShape) - .background(Color(0x80000000)) - .clickable(onClick = onClick), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.CameraRear, - contentDescription = "Switch Camera", - tint = Color.White, - modifier = Modifier.size(24.dp) - ) - } -} diff --git a/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt b/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt index 551ede7..92247b0 100644 --- a/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt +++ b/app/src/main/java/no/naiv/tiltshift/util/HapticFeedback.kt @@ -5,8 +5,6 @@ import android.os.Build import android.os.VibrationEffect import android.os.Vibrator import android.os.VibratorManager -import android.view.HapticFeedbackConstants -import android.view.View /** * Provides haptic feedback for user interactions. @@ -86,13 +84,4 @@ class HapticFeedback(private val context: Context) { vibrator.vibrate(longArrayOf(0, 50, 30, 50, 30, 50), -1) } } - - companion object { - /** - * Use system haptic feedback on a View for standard interactions. - */ - fun performHapticFeedback(view: View, feedbackConstant: Int = HapticFeedbackConstants.VIRTUAL_KEY) { - view.performHapticFeedback(feedbackConstant) - } - } }