ExifInterface GPS не читается на Android Q/10
У меня проблема из-за того, что Android 10 не может считывать информацию GPS из моих файлов jpeg. Точно такие же файлы работают на Android 9. Я попробовал ExifInterface (androidx), который возвращает null, а также изображение apache commons, которое говорит: "GPSLatitude: Invalid rational (0/0), Invalid rational (0/0)". Другая информация 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 возвращают null на Android Q/10. На Android 9 работает. Моя тестовая фотография действительно содержит информацию GPS. Даже сам Android не смог проиндексировать местоположение GPS в своем магазине мультимедиа. Поле также является нулевым в их базе данных. Передал тестовое фото по почте.
1 ответ
Как упоминалось в разработчике Android, теперь на Android 10 расположение встраиваемых файлов изображений напрямую не доступно приложениям:
Однако, поскольку эта информация о местоположении является конфиденциальной, Android 10 по умолчанию скрывает эту информацию от вашего приложения, если оно использует ограниченное хранилище.
По той же ссылке вы можете узнать, как исправить:
Запросить
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
) для доступа к файлу, поскольку теперь вы не можете получить доступ к файлу, используя его путь к файлу.