Android使用ExifInterface读取图片EXIF经纬度坐标返回null问题求助
问题原因及解决方案
路径类型不兼容
ExifInterface 接收字符串参数的构造方法仅支持解析本地文件路径,若你传入的url是content://开头的媒体库Uri,直接传入字符串无法正确读取完整EXIF属性,这是最常见的触发原因。低版本权限缺失
Android 9及更早系统没有ACCESS_MEDIA_LOCATION权限,要读取外部存储图片的EXIF位置信息,必须先申请READ_EXTERNAL_STORAGE权限,你当前的权限配置没有覆盖Android 9的场景。分区存储元数据拦截
Android 10及以上系统开启分区存储后,即便已申请ACCESS_MEDIA_LOCATION权限,默认拿到的媒体流会移除位置敏感元数据,需要通过MediaStore.setRequireOriginal(Uri)方法获取包含完整EXIF的原始文件流。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
相关产品推荐
相关产品推荐

