Android Q/10上无法读取ExifInterface的GPS信息

3
我遇到了这样的问题,Android 10无法从我的jpeg文件中读取GPS信息。但在Android 9中,完全相同的文件可以正常工作。 我尝试了ExifInterface(androidx),但它返回null;同时apache commons imaging表示“GPSLatitude: Invalid rational (0/0), Invalid rational (0/0)。” 像评分或XPKeywords等其他exif信息可以被正确读取。 如何解决这个问题? 测试代码:
import androidx.exifinterface.media.ExifInterface;
ExifInterface exif2 = new ExifInterface(is);
double[] latLngArray = exif2.getLatLong();

getLatLong 实现:

public double[] getLatLong() {
    String latValue = getAttribute(TAG_GPS_LATITUDE);
    String latRef = getAttribute(TAG_GPS_LATITUDE_REF);
    String lngValue = getAttribute(TAG_GPS_LONGITUDE);
    String lngRef = getAttribute(TAG_GPS_LONGITUDE_REF);
    if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
        try {
            double latitude = convertRationalLatLonToDouble(latValue, latRef);
            double longitude = convertRationalLatLonToDouble(lngValue, lngRef);
            return new double[] {latitude, longitude};
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "Latitude/longitude values are not parseable. " +
                    String.format("latValue=%s, latRef=%s, lngValue=%s, lngRef=%s",
                            latValue, latRef, lngValue, lngRef));
        }
    }
    return null;
}

所有的getAttribute调用在Android Q/10上都返回null。在Android 9上它是可以工作的。我的测试照片包含GPS信息,但是甚至Android本身也无法将GPS位置索引到他们的媒体存储中。他们数据库中的字段也为空。我通过邮件传输了测试照片。

你是如何打开那些文件的?在Android 10中,文件访问方式已经改变了... - guipivoto
1个回答

8

如在开发人员Android文档中提到的那样,在 Android 10 上,嵌入在图像文件中的位置信息对于应用程序不是直接可用的:

由于这些位置信息很敏感,因此如果应用程序使用作用域存储,则 Android 10 默认会将此信息隐藏起来,不会向应用程序公开。

在同一链接上,您可以查看如何修复:

  1. 在您的应用程序清单中请求ACCESS_MEDIA_LOCATION权限。

  2. 从您的MediaStore对象中调用setRequireOriginal(),传递照片的URI,如以下代码片段所示:

代码片段:

Uri photoUri = Uri.withAppendedPath(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        cursor.getString(idColumnIndex));

// Get location data from the ExifInterface class.
photoUri = MediaStore.setRequireOriginal(photoUri);
InputStream stream = getContentResolver().openInputStream(photoUri);
if (stream != null) {
    ExifInterface exifInterface = new ExifInterface(stream);
    // Don't reuse the stream associated with the instance of "ExifInterface".
    stream.close();
} else {
    // Failed to load the stream, so return the coordinates (0, 0).
    latLong = new double[2];
}

注意现在他们正在使用 UriInputStream (还有 FileDescriptor) 来访问文件,因为现在你无法使用文件路径来访问文件。

MediaStore仍然返回null。"此常量在API级别29中已被弃用。由于隐私原因,位置详细信息不再进行索引,并且此值现在始终为null。" --> https://developer.android.com/reference/android/provider/MediaStore.Images.ImageColumns - Denny Weinberg
你必须使用其中一种新方法进行读取:(例如ExifInterface.getLatLong(float[])) - guipivoto
1
无法工作的解决方案!exifInterface.getLatLong(latLong)总是返回纬度和经度的0.0值。但是坐标存在于图像中-在图像查看器中,我可以看到这些信息。有人能帮忙解决这个问题吗? - Vitaly
有人找到解决方案了吗?在Android 12上不起作用。 - Krutika Chotara
@KrutikaChotara,你找到 Android 12 的解决方案了吗? - martin petrov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接