Connect with us

Разработка

Остерегайтесь READ_MEDIA_IMAGES

В этом посте поделимся опытом того, как добавление этого разрешения в манифест заблокировало нам возможность выпустить приложение в альфа-канал, и почему вы должны быть осторожны, прежде чем добавлять это разрешение в свой проект.

Опубликовано

/

     
     

Если вы являетесь Android-разработчиком, то, возможно, знаете о недавнем изменении политики Google Play в отношении разрешения READ_MEDIA_IMAGES. К сожалению, мы не знали. В этом посте поделимся опытом того, как добавление этого разрешения в манифест заблокировало нам возможность выпустить приложение в альфа-канал, и почему вы должны быть осторожны, прежде чем добавлять это разрешение в свой проект.

Пример использования

Что мы хотели создать: кнопку открытия галереи с предварительным просмотром, которая отображает превью последнего изображения из потока камеры.

Остерегайтесь READ_MEDIA_IMAGES

Чтобы реализовать нечто подобное, приложение может запросить доступ ко всем изображениям, а затем запросить последнее из них с помощью MediaStore API:

private fun getLatestImageUri(): Uri? {
    val projection = arrayOf(
      MediaStore.Images.Media._ID,
      MediaStore.Images.ImageColumns.DATA,
      MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
      MediaStore.Images.ImageColumns.DATE_TAKEN,
      MediaStore.Images.ImageColumns.MIME_TYPE
    )
    val sortOrder = "${MediaStore.Images.Media.DATE_TAKEN} DESC"

    return context?.contentResolver?.query(
      // uri =
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
      // projection =
      projection,
      // selection =
      null,
      // selectionArgs =
      null,
      // sortOrder =
      sortOrder
    )?.use { cursor ->
      if (cursor.moveToFirst()) { // Read the first row only
        val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
        val id = cursor.getLong(idColumn)
        return ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
      }
      null
    }
  }

Поскольку этот запрос сможет получать результаты из внешних источников (обратите внимание, мы используем EXTERNAL_CONTENT_URI), только если приложение имеет к ним доступ, мы должны запросить разрешение на доступ к изображениям в рантайме.

Согласно документации, READ_EXTERNAL_STORAGE не имеет эффекта, начиная с API уровня 33. Если ваше приложение получает доступ к медиафайлам других приложений, нам нужно запросить одно или несколько из этих разрешений: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO. Именно так мы и поступили.

Поскольку наше приложение поддерживает минимальную версию SDK 29, нам нужно было запросить два разных разрешения:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
  • READ_EXTERNAL_STORAGE был необходим для устройств под управлением Android 10-12 (API 29-32)
  • READ_MEDIA_IMAGES требовалось для устройств под управлением Android 13+ (API 33 и выше)

В процессе разработки все шло хорошо, но когда мы попытались выложить обновление на наш альфа-канал в Play Store, мы столкнулись с серьезной проблемой.

Отказ Play Store

22 января 2025 года Google ввел новую политику, требующую от разработчиков предоставления декларации, обосновывающей использование READ_MEDIA_IMAGES. Если эта форма не была отправлена (или не была одобрена), обновления приложения блокировались.

Вот точное сообщение об ошибке, которое мы получили:

22 января 2025 года: Разработчики должны представить декларацию. Обратите внимание на следующее:
Разработчики, не предоставившие заполненную форму декларации к этой дате, будут заблокированы в обновлении своего приложения.

Присмотревшись повнимательнее, мы поняли, что критерии одобрения очень строгие. Именно поэтому Google предупредил разработчиков за 2 года, чтобы они успели соответствовать требованиям. Следующие сценарии использования точно будут затронуты:

  • Приложения галереи (приложения, предназначенные для управления пользовательскими медиафайлами)
  • Приложения для редактирования фотографий
  • Приложения для социальных сетей с функциями обмена изображениями.

Такие приложения, как Instagram*, используют это разрешение, потому что их основные сценарии использования соответствуют поддерживаемым:

Остерегайтесь READ_MEDIA_IMAGES

Однако наш вариант использования — отображение предварительного просмотра последнего изображения из галереи — может относиться как к «широкому доступу», так и к «редкому использованию», в зависимости от того, как вы это видите.

Остерегайтесь READ_MEDIA_IMAGES

Если Play считает наш случай использования единичным, нам предлагается не использовать это разрешение. Если бы мы захотели обосновать использование «широким доступом», нам пришлось бы подавать декларацию и ждать, пока они одобрят или отклонят ее, а это лотерея.

Основываясь на предыдущем опыте блокировки приложения из-за использования опасных разрешений (еще один случай отказа был связан с READ_CALL_LOG, который мы решили только удалением этого разрешения), мы решили, что выиграть эту битву будет непросто, и решили, что пока лучше воздержаться от этого разрешения.

Решение

Мы изменили функцию, чтобы избежать ненужных задержек и разблокировать релиз. На данный момент самое простое решение следующее:

Остерегайтесь READ_MEDIA_IMAGES

В дальнейшем нам придется либо планировать выпуск этой фичи должным образом, либо представить ее в качестве «широкого доступа» и надеяться на лучшее, либо вложить больше средств в поиск альтернативного подхода, не требующего дополнительных разрешений, для получения доступа к последнему изображению из потока камеры.

Подумайте дважды, прежде чем использовать READ_MEDIA_IMAGES

Если вы решили добавить READ_MEDIA_IMAGES в свое приложение, мы настоятельно рекомендуем:

  1. Прочитать официальную политику Google
  2. Оценить свой сценарий использования — спланировать релиз. Если ваше приложение не является галерейным, фото- или медиа-приложением, ожидайте некоторой вероятности отказа и имейте План B.
  3. Заранее протестировать свое приложение — если вы не уверены, что ваш вариант использования будет одобрен, быстро протестируйте обновление с разрешением. Так как у нас быстрая обратная связь, между разработкой и релизом прошло совсем немного времени, и мы смогли обнаружить эту проблему.
  4. Рассмотреть альтернативные решения — поговорите с вашими дизайнерами. На данный момент мы используем жестко прописанное изображение для кнопки. Вы также можете использовать Media Store API без запроса полного доступа к изображениям, то есть у вас будет доступ только к изображениям, полученным вашим приложением (используйте INTERNAL_CONTENT_URI), и, возможно, этого будет достаточно для вашего случая использования.

Мы надеемся, что этот пост поможет другим разработчикам избежать ненужных разочарований. Если вы сталкивались с подобными проблемами или нашли обходные пути, не стесняйтесь поделиться своим опытом.

Счастливого Андроида!

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: