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

Android 12中ExifInterface获取图片位置信息失效问题咨询

问题原因

Android 10(API 29)及以上版本对媒体文件的位置元数据做了隐私加密处理,现有逻辑不满足新版本的读取规则:

  • 仅在清单文件声明ACCESS_MEDIA_LOCATION不会自动生效,该权限属于运行时权限,需要主动向用户申请授权
  • 直接通过ContentResolver.openInputStream()获取的媒体Uri输入流,系统会默认抹除所有GPS相关的Exif标签,读到的是脱敏后的文件数据,自然拿不到位置信息
  • Android 9及以下版本没有这套脱敏机制,所以原有逻辑可以正常运行
修复步骤
  1. 先在代码中动态申请ACCESS_MEDIA_LOCATION权限,确认用户授权后再执行位置读取逻辑
  2. 针对API 29及以上版本,读取Exif前先调用MediaStore.setRequireOriginal()获取未脱敏的原始文件Uri,再基于这个Uri构造ExifInterface读取GPS字段
  3. 流的关闭逻辑放到Exif解析完成之后,避免解析过程中流被提前释放导致异常

修正后的可运行代码如下:

boolean hasLatLong = false;
Uri imageUri = imagePickerModel.getUri();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
    // 校验媒体位置权限是否已授权
    if (ContextCompat.checkSelfPermission(v.getContext(), Manifest.permission.ACCESS_MEDIA_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        InputStream inputStream = null;
        try {
            // 获取未做位置脱敏的原始图片Uri
            Uri originalImageUri = MediaStore.setRequireOriginal(imageUri);
            inputStream = v.getContext().getContentResolver().openInputStream(originalImageUri);
            if (inputStream != null) {
                ExifInterface exifInterface = new ExifInterface(inputStream);
                hasLatLong = exifInterface.getLatLong() != null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 解析完成后再关闭流
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
} else {
    hasLatLong = exif.getLatLong() != null;
}

注意:如果图片来自第三方私有目录、本身没有写入GPS元数据,或者用户拒绝了位置权限授权,getLatLong()依然会返回null,需要对应做好空值兼容。

内容的提问来源于stack exchange,提问作者Krutika Chotara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:33:21