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" />
Рантим захтев за 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 — системски пикер који такође не захтева приступ целој библиотеци. 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 координате поверљивим подацима.
Користите системски пикер: 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође