MediaScanner и ScopedStorage в SDK-29

Приложение , над которым я работаю, использует Fileв качестве мишени для фотосъемки. это выполняется извне, когда пользователь выбирает приложение камеры с помощьюIntent(ACTION_IMAGE_CAPTURE). после обновления build и target-sdk до 29 возник ряд проблем, начиная с ограничения на свободный доступ к файлам на внешнем хранилище. первое изменение заключалось в использовании одного из каталогов частного кеша приложения, например:

File.createTempFile("tempImage", ".jpg", context.cacheDir)

или каталог частного внешнего хранилища приложений:

File.createTempFile("tempImage", ".jpg", context.getExternalFilesDir(Environment.DIRECTORY_PICTURES))

в сочетании с доступом FileProvider в file_paths.xml, например:

<paths>
    <external-path name="images" path="Pictures/" /><!-- prior to SDK-29, use public external storage -->
    <external-files-path name="externalImages" path="Pictures/" />
    <files-path name="internalImages" path="internalImages/"/>
    <cache-path name="cache" path="/" />
</paths>

теперь они работают нормально после правильной настройки, однако реализация функции "Сохранить в галерею", например: уведомление других приложений о новых изображениях больше не работает на устройствах под управлением Android-10

// use FileProvider to make this new photo publicly accessible 
val shareableUri = FileProvider.getUriForFile(context, FILE_PROVIDER_AUTHORITY, newImage)
context.sendBroadcast(
  Intent(ACTION_MEDIA_SCANNER_SCAN_FILE).apply { data = uris.externalUri }
)

этот подход должен работать, но не работает, независимо от того, где сохранено исходное изображение (private-app-dir, cache-dir, external-private)

MediaScannerConnection.scanFile(context, arrayOf(newImage.absolutePath), arrayOf("image/jpeg")) { path: String, uri: Uri? ->
  if (uri == null) {
    throw IllegalStateException("media scan failed...")
  } else {
    // successful
  }
}

Есть ли новые ограничения в Android SDK-29, которые требуют изменения в MediaScanning, в частности, связанных со способом сканирования (потенциально) частного файла изображения? Я заметил, чтоMediaScanner методы в основном ожидают String path вместо URI, поэтому это наводит меня на мысль, что новые ограничения не будут применяться к нему, поскольку это системный компонент.

1 ответ

Приложениям, ориентированным на Android 10 (уровень API 29) и выше, по умолчанию предоставляется ограниченный доступ к внешнему запоминающему устройству или ограниченному хранилищу.

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

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

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

посетите эту ссылку для получения дополнительной информации: https://developer.android.com/training/data-storage/files/external-scoped

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