【问题标题】:ExifInterface GPS not read on Android Q/10在 Android Q/10 上无法读取 ExifInterface GPS
【发布时间】:2019-09-17 19:33:46
【问题描述】:

我遇到了 Android 10 无法从我的 jpeg 文件中读取 GPS 信息的问题。完全相同的文件适用于 Android 9。 我尝试了返回 null 的 ExifInterface (androidx),以及显示“GPSLatitude:无效理性 (0/0),无效理性 (0/0)”的 apache commons 成像。 其他 exif 信息(如评级或 XPKeywords)被正确读取。

如何解决?

测试代码:

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 中的文件访问权限已更改...

标签: android exif androidx android-10.0 android-exifinterface


【解决方案1】:

in developer android 所述,现在,在 Android 10 上,嵌入图像文件的位置无法直接供应用使用:

但是,由于此位置信息很敏感,因此默认情况下,Android 10 会在您的应用使用范围存储时隐藏此信息。

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

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

  2. 从你的MediaStore对象中,调用setRequireOriginal(),传入照片的URI,如下代码sn-p所示:

代码sn-p:

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 中已弃用。出于隐私原因,不再索引位置详细信息,并且此值现在始终为空。” --> developer.android.com/reference/android/provider/…
  • 您必须使用其中一种新方法进行阅读:(例如,ExifInterface.getLatLong(float[]))
  • 链接不再有效。 idColumnIndex 和 cursor 是什么?
  • 是否也可以使用 setRequireOriginal() 来修改通过 Intent 传递的 Uri,以便将照片共享到另一个应用程序?请参阅问题以获取更多详细信息:stackoverflow.com/questions/68442139/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多