Android 7设置图片Exif数据始终报错,Android 8运行正常
解决Android 7中Exif GPS标签格式不匹配的问题
我之前也碰到过类似的版本兼容问题——Android 7及以下的ExifInterface对GPS标签的格式要求比Android 8+严格太多,直接传字符串格式的坐标会触发格式不匹配警告,导致Exif数据保存失败。
问题根源
Android 7(API 25及以下)的ExifInterface要求GPSLatitude、GPSLongitude这类标签的值必须是URATIONAL类型(也就是由「分子/分母」组成的有理数格式),而你的代码应该是直接把计算后的数值转成字符串传入,不符合低版本的格式要求。Android 8+的ExifInterface做了兼容优化,能自动解析字符串格式的坐标,但低版本没有这个能力。
两种解决方案
方案一:使用官方兼容方法(推荐)
ExifInterface提供了现成的setLatLong(double latitude, double longitude)方法,这个方法会自动处理不同版本的格式转换,不用自己手动拼接格式,代码更简洁可靠:
public void geoTag(String filename, double lng, double lat){ ExifInterface exif; try { exif = new ExifInterface(filename); // 直接调用setLatLong,内部自动处理格式兼容 exif.setLatLong(lat, lng); // 一定要记得保存修改 exif.saveAttributes(); } catch (IOException e) { e.printStackTrace(); } }
方案二:手动生成URATIONAL格式字符串
如果你需要手动控制格式,可以把经纬度拆分成度、分、秒的有理数形式,拼接成符合要求的字符串:
// 把经纬度转换成Exif要求的URATIONAL格式字符串 private String convertToExifRational(double value) { boolean isNegative = value < 0; value = Math.abs(value); // 拆分度、分、秒 int degrees = (int) Math.floor(value); double remainder = value - degrees; int minutes = (int) Math.floor(remainder * 60); remainder = remainder * 60 - minutes; // 秒保留6位小数,转成分子分母形式 int secondsNumerator = (int) Math.round(remainder * 1000000); int secondsDenominator = 1000000; // 拼接成"度/1,分/1,秒分子/秒分母"的格式,负数要加负号 StringBuilder sb = new StringBuilder(); if (isNegative) { sb.append("-"); } sb.append(degrees).append("/1,") .append(minutes).append("/1,") .append(secondsNumerator).append("/").append(secondsDenominator); return sb.toString(); } // 修改后的geoTag方法 public void geoTag(String filename, double lng, double lat){ ExifInterface exif; try { exif = new ExifInterface(filename); // 设置纬度和纬度方向(N/S) exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, convertToExifRational(lat)); exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, lat >= 0 ? "N" : "S"); // 设置经度和经度方向(E/W) exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, convertToExifRational(lng)); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, lng >= 0 ? "E" : "W"); // 保存修改 exif.saveAttributes(); } catch (IOException e) { e.printStackTrace(); } }
验证
替换代码后,Android 7设备就不会再触发格式不匹配的警告,Exif的GPS数据也能正常保存了。
内容的提问来源于stack exchange,提问作者Magobin
相关产品推荐
相关产品推荐

