From 697a6cae8735eb124127e2017e4bacd53f7a8149 Mon Sep 17 00:00:00 2001 From: Developer Date: Mon, 20 Apr 2026 21:32:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=86=99=E5=85=A5=20EXIF=20GPS/?= =?UTF-8?q?=E6=97=B6=E9=97=B4/=E7=9B=B8=E6=9C=BA=E5=9E=8B=E5=8F=B7/?= =?UTF-8?q?=E4=BD=9C=E8=80=85=EF=BC=8C=E4=BF=9D=E5=AD=98=E6=97=B6=E5=B8=A6?= =?UTF-8?q?=E7=BA=AC=E5=BA=A6=E7=BB=8F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 3 + .../inspection/camera/util/ImageProcessor.kt | 56 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) 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) + } + } }