Android Q/10 未读取 ExifInterface GPS
ExifInterface GPS not read on Android Q/10
我遇到的问题是 Android 10 无法从我的 jpeg 文件中读取 GPS 信息。完全相同的文件正在 Android 9 上运行。
我尝试了 returns null 的 ExifInterface (androidx),以及表示 "GPSLatitude: Invalid rational (0/0), Invalid rational (0/0)" 的 apache commons imaging。
其他 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 返回空值。在 Android 9 它正在工作。我的测试照片确实包含 GPS 信息。
甚至 Android 本身也无法将 GPS 位置索引到他们的媒体存储中。该字段在他们的数据库中也是空的。我通过邮件传输了测试照片。
如前所述 in developer android,现在,在 Android 10,嵌入图像文件的位置不能直接供应用程序使用:
Because this location information is sensitive, however, Android 10 by default hides this information from your app if it uses scoped storage.
在同一个 link 上,您可以查看如何修复:
在您的应用清单中请求 ACCESS_MEDIA_LOCATION
权限。
从您的 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];
}
请注意他们现在如何使用 Uri
、InputStream
(以及 FileDescriptor
)访问文件,因为现在您无法使用文件路径访问文件。
我遇到的问题是 Android 10 无法从我的 jpeg 文件中读取 GPS 信息。完全相同的文件正在 Android 9 上运行。 我尝试了 returns null 的 ExifInterface (androidx),以及表示 "GPSLatitude: Invalid rational (0/0), Invalid rational (0/0)" 的 apache commons imaging。 其他 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 返回空值。在 Android 9 它正在工作。我的测试照片确实包含 GPS 信息。 甚至 Android 本身也无法将 GPS 位置索引到他们的媒体存储中。该字段在他们的数据库中也是空的。我通过邮件传输了测试照片。
如前所述 in developer android,现在,在 Android 10,嵌入图像文件的位置不能直接供应用程序使用:
Because this location information is sensitive, however, Android 10 by default hides this information from your app if it uses scoped storage.
在同一个 link 上,您可以查看如何修复:
在您的应用清单中请求
ACCESS_MEDIA_LOCATION
权限。从您的 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];
}
请注意他们现在如何使用 Uri
、InputStream
(以及 FileDescriptor
)访问文件,因为现在您无法使用文件路径访问文件。