diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ffcd022..238e517 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -100,6 +100,9 @@ dependencies { // Accompanist permissions implementation("com.google.accompanist:accompanist-permissions:0.32.0") + // ExifInterface + implementation("androidx.exifinterface:exifinterface:1.3.7") + // Testing testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") diff --git a/app/src/main/java/com/inspection/camera/util/ImageProcessor.kt b/app/src/main/java/com/inspection/camera/util/ImageProcessor.kt index 672d85d..cab6a62 100644 --- a/app/src/main/java/com/inspection/camera/util/ImageProcessor.kt +++ b/app/src/main/java/com/inspection/camera/util/ImageProcessor.kt @@ -1,6 +1,7 @@ package com.inspection.camera.util import android.content.ContentValues +import android.location.Location import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory @@ -15,7 +16,9 @@ import android.net.Uri import android.os.Build import android.os.Environment import android.provider.MediaStore +import android.util.Log import androidx.compose.ui.graphics.toArgb +import androidx.exifinterface.media.ExifInterface import com.inspection.camera.data.models.ImageItem import com.inspection.camera.data.models.ImageQuality import com.inspection.camera.data.models.MergeLayoutType @@ -539,7 +542,9 @@ object ImageProcessor { context: Context, bitmap: Bitmap, fileName: String, - quality: Int = 85 + quality: Int = 85, + latitude: Double? = null, + longitude: Double? = null ): Uri? { val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, fileName) @@ -558,6 +563,8 @@ object ImageProcessor { bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream) } + writeExifData(context, it, latitude, longitude) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { contentValues.clear() contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) @@ -567,4 +574,51 @@ object ImageProcessor { it } } + + /** + * 写入 EXIF 信息:GPS位置、拍摄时间、相机型号、作者 + */ + private fun writeExifData( + context: Context, + uri: Uri, + latitude: Double?, + longitude: Double? + ) { + try { + context.contentResolver.openFileDescriptor(uri, "rw")?.use { pfd -> + val exif = ExifInterface(pfd.fileDescriptor) + + // 写入 GPS 信息 + if (latitude != null && longitude != null) { + // 使用 Location 对象包装坐标,避免 API 版本兼容问题 + val loc = Location("CheckShot").apply { + this.latitude = latitude + this.longitude = longitude + } + // ExifInterface (AndroidX) 提供了 setGpsInfo(Location) 接口 + exif.setGpsInfo(loc) + } + + // 写入拍摄时间 + val dateTimeFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault()) + val dateTimeStr = dateTimeFormat.format(Date()) + exif.setAttribute(ExifInterface.TAG_DATETIME, dateTimeStr) + exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateTimeStr) + exif.setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED, dateTimeStr) + + // 写入相机型号(项目名称) + // 尽量把 MODEL 设置为项目名称,MAKE 为较通用的相机厂商名 + exif.setAttribute(ExifInterface.TAG_MAKE, "巡检相机") + exif.setAttribute(ExifInterface.TAG_MODEL, "anroid-CheckShot") + + // 写入作者 + exif.setAttribute(ExifInterface.TAG_ARTIST, "xiaji") + + exif.saveAttributes() + Log.d("ImageProcessor", "EXIF data written successfully") + } + } catch (e: Exception) { + Log.e("ImageProcessor", "Failed to write EXIF data", e) + } + } }