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 по умолчанию скрывает эту информацию от вашего приложения, если оно использует ограниченное хранилище.

По той же ссылке вы можете узнать, как исправить:

  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];
}

Обратите внимание, как они сейчас используют Uri, InputStream (а также FileDescriptor) для доступа к файлу, поскольку теперь вы не можете получить доступ к файлу, используя его путь к файлу.

Другие вопросы по тегам