You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用ExifInterface读取图片EXIF经纬度坐标返回null问题求助

问题原因及解决方案

  1. 路径类型不兼容
    ExifInterface 接收字符串参数的构造方法仅支持解析本地文件路径,若你传入的url是content://开头的媒体库Uri,直接传入字符串无法正确读取完整EXIF属性,这是最常见的触发原因。

  2. 低版本权限缺失
    Android 9及更早系统没有ACCESS_MEDIA_LOCATION权限,要读取外部存储图片的EXIF位置信息,必须先申请READ_EXTERNAL_STORAGE权限,你当前的权限配置没有覆盖Android 9的场景。

  3. 分区存储元数据拦截
    Android 10及以上系统开启分区存储后,即便已申请ACCESS_MEDIA_LOCATION权限,默认拿到的媒体流会移除位置敏感元数据,需要通过MediaStore.setRequireOriginal(Uri)方法获取包含完整EXIF的原始文件流。

  4. ExifInterface版本问题
    如果你使用的是系统framework自带的android.media.ExifInterface,低版本系统存在大量解析兼容性问题,建议替换为Jetpack库提供的androidx.exifinterface.media.ExifInterface,确保不同系统版本的解析逻辑一致。


修正后的参考代码

// 首先确保你已在build.gradle引入Jetpack ExifInterface依赖:
// implementation "androidx.exifinterface:exifinterface:1.3.7"

fun readLatLong(context: Context): Pair<Double, Double>? {
    try {
        val uri = Uri.parse(url)
        // 处理content类型的Uri
        val inputStream = if (uri.scheme == "content") {
            // Android 10+需要获取原始流
            val requestUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                MediaStore.setRequireOriginal(uri)
            } else uri
            context.contentResolver.openInputStream(requestUri)
        } else {
            // 本地文件路径直接打开流
            FileInputStream(url)
        }
        inputStream?.use { stream ->
            val exifInterface = ExifInterface(stream)
            exifInterface.latLong?.let {
                if (it.size == 2) {
                    return Pair(it[0], it[1])
                }
            }
        }
    } catch (e: Exception) {
        Timber.e(e, "Reading latLong failed")
    }
    return null
}

内容的提问来源于stack exchange,提问作者Bipin Vayalu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:06:02