Photo Library Permission — е разрешението, необходимо на приложението за достъп до снимки и видеоклипове, съхранявани на устройството на потребителя. То е необходимо за избор на изображения от галерията, запазване на медийни файлове и управление на фотоалбуми. Според Apple Developer Documentation, 2024, от iOS 14 нататък приложенията трябва да искат достъп до ограничена библиотека, а не до всички снимки наведнъж.
Основни точки
Photo Library Permission — е системно разрешение, което регулира достъпа на приложението до медийни файлове, съхранявани на устройството. То покрива както четене (преглед и избор на снимки и видеоклипове), така и запис (запазване на нови файлове в галерията). Мобилните платформи третират медийната библиотека като поверителни данни, тъй като снимките могат да съдържат лична и чувствителна информация.
На Android 13 (API 33) Google раздели единното разрешение READ_EXTERNAL_STORAGE на три отделни: READ_MEDIA_IMAGES за снимки, READ_MEDIA_VIDEO за видеоклипове и READ_MEDIA_AUDIO за аудио. Това позволява на потребителя да предостави достъп само до определен тип медийни файлове. На iOS, от iOS 14 нататък, PhotoKit предоставя на потребителя възможност да избере конкретни снимки за достъп, вместо да отвори цялата библиотека.
Според Counterpoint Research (2024), над 70% от мобилните приложения в категориите социални мрежи, комуникации и фоторедактори искат Photo Library Permission. В същото време 32% от потребителите отказват достъп до галерията, ако не разбират защо приложението се нуждае от техните снимки. Apple и Google препоръчват използването на системния PhotoPicker за избор на отделни файлове, без да се иска пълен достъп.
Достъп до галерията на Android се промени значително с пускането на Android 13. Вместо едно разрешение READ_EXTERNAL_STORAGE се появиха гранулирани разрешения за всеки тип медиен файл, което дава на потребителя по-голям контрол.
От Android 13 нататък за достъп до снимки се използва READ_MEDIA_IMAGES, а за видеоклипове — READ_MEDIA_VIDEO. Разрешението READ_EXTERNAL_STORAGE вече не предоставя достъп до медийни файлове — остана само за четене на не-медийни файлове от споделеното хранилище. Декларацията в манифеста изглежда така:
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
За обратна съвместимост с Android 12 и по-стари версии трябва да се декларира и READ_EXTERNAL_STORAGE. Въпреки това, Android 13 автоматично игнорира това разрешение, когато присъстват новите гранулирани разрешения. Използвайте атрибута android:maxSdkVersion="32" в манифеста за старото разрешение, за да го скриете на новите версии. Това предотвратява излишно искане на устройства с Android 13+.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
Runtime заявката за Photo Library Permission на Android се изпълнява чрез Activity Result API. Пример за заявка за достъп до изображения:
private val photoPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) {
loadGalleryImages()
} else {
showPermissionDenied()
}
}
fun pickPhoto() {
val permission = if (Build.version.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
Manifest.permission.READ_MEDIA_IMAGES
} else {
Manifest.permission.READ_EXTERNAL_STORAGE
}
if (ContextCompat.checkSelfPermission(this, permission)
== PackageManager.PERMISSION_GRANTED) {
loadGalleryImages()
} else {
photoPermissionLauncher.launch(permission)
}
}
Достъп до галерията на iOS се управлява чрез рамката PhotoKit и ключовете NSPhotoLibraryUsageDescription и NSPhotoLibraryAddUsageDescription в Info.plist. От iOS 14 нататък потребителят може да предостави достъп само до избрани снимки (Limited Photo Library).
За четене на снимки от библиотеката е необходим NSPhotoLibraryUsageDescription, за запис (запазване на снимки) — NSPhotoLibraryAddUsageDescription. Ако приложението само запазва медия, но не я чете, вторият ключ е достатъчен.
<key>NSPhotoLibraryUsageDescription</key>
<string>Приложението се нуждае от достъп до снимки, за да избере профилна снимка и да публикува изображения.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Приложението се нуждае от достъп, за да запази обработените снимки във вашата галерия.</string>
Заявката за достъп до снимки на iOS се изпълнява чрез PHPhotoLibrary.requestAuthorization. От iOS 14 нататък статусът .limited показва, че потребителят е предоставил достъп до ограничен набор от снимки.
import PhotosUI
func requestPhotoLibraryAccess() {
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async {
switch status {
case .authorized:
self.loadPhotoLibrary()
case .limited:
self.loadSelectedPhotos()
case .denied, .restricted:
self.showSettingsAlert()
case .notDetermined:
break
}
}
}
}
private func loadPhotoLibrary() {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let assets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
// Работа с резултатите от заявката
}
Статусът .limited на iOS 14+ означава, че потребителят е предоставил достъп само до няколко избрани снимки. Приложението може да поиска разширяване на достъпа чрез системен диалог, като извика PHPhotoLibrary.shared().presentLimitedLibraryPicker. Препоръчително е да показвате този диалог само когато потребителят изрично поиска функция, за която са необходими допълнителни снимки.
PhotoPicker — е системен компонент за избор на медийни файлове, който не изисква разрешение за достъп до цялата библиотека. От Android 13 и iOS 14 нататък Google и Apple препоръчват използването на PhotoPicker вместо искане на Photo Library Permission, ако приложението трябва само да избере една или няколко снимки.
На Android 13+ вграденият PhotoPicker (ActivityResultContracts.PickVisualMedia) позволява на потребителя да избере снимка или видеоклип, без да предоставя достъп до цялата галерия. Приложението получава само URI на избраните файлове. PhotoPicker работи без деклариране на каквито и да било разрешения в манифеста.
private val pickMedia =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// URI на избрания файл, без достъп до цялата библиотека
showImage(uri)
}
}
fun selectPhoto() {
pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
На iOS 14+ се появи PHPickerViewController — системен picker, който също не изисква достъп до цялата библиотека. PHPicker работи в отделен процес и няма достъп до библиотеката на приложението. Това е предпочитаният начин за избор на снимки в повечето сценарии.
import PhotosUI
func presentPhotoPicker() {
var config = PHPickerConfiguration()
config.selectionLimit = 1
config.filter = .images
let picker = PHPickerViewController(configuration: config)
picker.delegate = self
present(picker, animated: true)
}
PhotoPicker не е подходящ, ако приложението се нуждае от достъп до цялата библиотека за масови операции: архивиране, синхронизация с облака, приложение-галерия, файлов мениджър. В тези случаи трябва да се поиска Photo Library Permission и да се обработи случаят на ограничен достъп (Limited). За iOS е задължително добавянето на обработка на статуса .limited и предлагане на потребителя да разшири достъпа.
Най-добри практики за работа с Photo Library Permission помагат за намаляване на броя на отказите и спазване на изискванията за поверителност на платформите.
За избор на една или няколко снимки използвайте системния PhotoPicker или PHPicker. Тези компоненти не изискват разрешения и осигуряват най-доброто потребителско изживяване. Пълно разрешение за достъп до галерията искайте само ако функционалността на приложението изисква достъп до цялата медийна библиотека. Google и Apple изрично препоръчват този подход в документацията за разработчици.
Ако приложението наистина се нуждае от пълен достъп до галерията, покажете предварителен екран с обяснение. Обяснете защо са необходими всички снимки, а не само една. Например приложение за архивиране трябва да обясни, че ще сканира всички медийни файлове за създаване на копие. Pre-permission screen е особено важен на iOS поради механизма Limited Access.
Ако приложението само запазва снимки, но не ги чете (напр. фоторедактор, който запазва резултата), искайте само разрешение за запис в галерията. На Android това е WRITE_EXTERNAL_STORAGE (за Android 12 и по-стари) или MediaStore API без разрешения (за Android 10+). На iOS използвайте NSPhotoLibraryAddUsageDescription без NSPhotoLibraryUsageDescription.
Често задавани въпроси
От Android 10 (API 29) нататък запазването на снимки чрез MediaStore не изисква разрешение WRITE_EXTERNAL_STORAGE. Системата предоставя достъп до споделеното хранилище за запис без изрично разрешение. За четене на чужди файлове все още е необходимо съответното разрешение.
READ_EXTERNAL_STORAGE — старо разрешение за четене на всички файлове от споделеното хранилище (до Android 12). READ_MEDIA_IMAGES — ново гранулирано разрешение за четене само на изображения (Android 13+). Потребителят може да предостави достъп само до снимки, отказвайки достъп до видеоклипове и аудио.
Статусът .limited означава, че потребителят е избрал няколко снимки за достъп. Приложението може да покаже системния диалог за разширяване чрез PHPhotoLibrary.shared().presentLimitedLibraryPicker. Препоръчително е да показвате този диалог само при изрично искане на потребителя, например при натискане на бутона „Добавяне на още снимки".
Да, при наличие на Photo Library Permission приложението може да чете EXIF данни, включително геоетикети, дата на заснемане и модел на камерата. На iOS за достъп до геоетикети може да е необходимо допълнително Location Permission, тъй като Apple счита GPS координатите за поверителни данни.
Използвайте системния picker: PHPicker с filter = .videos на iOS, PickVisualMedia с VideoOnly на Android. На Android за избор на видеоклип от галерията може да се използва и Intent(Intent.ACTION_PICK) с MediaStore.Video.Media.EXTERNAL_CONTENT_URI, но това изисква разрешение READ_EXTERNAL_STORAGE на версии под Android 13.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също