Povolení přístupu ke kontaktům je mechanismus mobilních operačních systémů vyžadující výslovný souhlas uživatele před čtením adresáře zařízení. Na iOS je přístup ke kontaktům realizován přes CNContactStore a na Androidu přes Contacts API a systém runtime permissions. Podle Apple Developer Documentation, 2025 musí od iOS 18 všechny aplikace používat jednotné Contacts Access API. Správná implementace žádosti o povolení zvyšuje šance na schválení moderací obchodů s aplikacemi.
Hlavní body
Povolení přístupu k kontaktům je mechanismus operačního systému, který chrání adresář uživatele před neoprávněným čtením aplikacemi třetích stran. V mobilních operačních systémech jsou kontakty považovány za důvěrné údaje, protože obsahují jména, telefonní čísla, e-mailové adresy a fotografie osob z okolí uživatele.
Na iOS je povolení regulováno frameworkem Contacts a třídou CNContactStore. Uživatel vidí systémový dialog při první žádosti o přístup, kde může zvolit poskytnutí přístupu nebo odmítnutí žádosti. Na Androidu je ochrana založena na systému runtime permissions: aplikace uvádí READ_CONTACTS v manifestu a vyžaduje jej za běhu prostřednictvím ActivityResultLauncher nebo fragmentu se zpracováním výsledku.
Podle údajů Statista (2025) více než 68% uživatelů iOS a 54% uživatelů Androidu odmítá přístup ke kontaktům při první žádosti aplikace. To znamená, že vývojář musí nejen správně implementovat žádost, ale také vysvětlit uživateli důvod potřeby přístupu.
Průmyslový standard — žádat o přístup pouze v okamžiku, kdy je funkčnost skutečně potřebná, ne při prvním spuštění. Tento přístup snižuje procento odmítnutí a zlepšuje uživatelský zážitek.
V ekosystému Apple je přístup ke kontaktům regulován frameworkem Contacts, představeným v iOS 9. Třída CNContactStore poskytuje metody pro vyžádání povolení a provádění operací čtení a zápisu. Při prvním volání requestAccess(for:) systém zobrazí nativní dialog s vysvětlením důvodu přístupu.
Od iOS 17 Apple zavedl režim jednorázového přístupu (single contact access). Uživatel může vybrat jeden kontakt z adresáře a předat jej aplikaci bez odhalení celé databáze. Režim je implementován prostřednictvím CNContactPickerViewController a nevyžaduje volání requestAccess(for:).
Vývojář musí pochopit: pokud aplikace žádá o plný přístup, ale funkčně jí stačí jeden kontakt, moderátoři App Store mohou build odmítnout. Podle Apple App Review Guidelines (2025), sekce 5.1.1, je výslovně vyžadováno minimální nezbytné množství dat.
S vydáním iOS 18 Apple zpřísnil požadavky na Privacy Manifest — soubor privacy.xcprivacy, ve kterém vývojář deklaruje důvod přístupu k chráněným datům. Pro kontakty se používá klíč NSContactsUsageDescription s lokalizovaným textem zobrazeným v systémovém dialogu.
Bez správného privacy manifestu aplikace neprojde moderací App Store Connect. Text popisu musí být konkrétní: ne „Pro zlepšení fungování”, ale „Pro vyhledávání přátel podle telefonního čísla”.
Na Androidu je přístup ke kontaktům chráněn povolením READ_CONTACTS, které patří do kategorie nebezpečných (dangerous) — musí být vyžadováno za běhu, nejen při instalaci. Mechanismus runtime permissions byl zaveden v Android 6.0 (API 23) a zůstává hlavním způsobem ochrany důvěrných dat.
Povolení READ_CONTACTS je uvedeno v manifestu přes tag uses-permission a vyžadováno v kódu přes ActivityResultLauncher nebo fragment s onRequestPermissionsResult. Uživatel může žádost odmítnout nebo zvolit možnost „Znovu se neptat”, po které musí aplikace odmítnutí správně zpracovat.
Od Android 14 (API 34) se chování runtime permissions změnilo: při odmítnutí dvou po sobě jdoucích žádostí operační systém automaticky nastaví příznak neverAskAgain. Podle Google Developer Documentation (2024) by měl vývojář zkontrolovat stav přes shouldShowRequestPermissionRationale před opětovnou žádostí.
Pro čtení kontaktů Android používá ContentProvider s názvem ContactsContract. Jedná se o strukturovanou databázi přístupnou přes ContentResolver. Data jsou organizována do několika tabulek: Contacts (kontakty), RawContacts (surové záznamy z různých účtů), Data (detailní informace: telefony, e-mail, adresy).
Dotaz na ContactsContract se provádí přes URI ContactsContract.Contacts.CONTENT_URI. Vývojář by měl požadovat minimum sloupců a používat projekci pro filtrování polí — to urychluje provádění dotazu a snižuje spotřebu paměti.
Praktická implementace žádosti o přístup ke kontaktům se liší na iOS a Androidu. Níže jsou uvedeny konkrétní příklady v Swift a Kotlin se zpracováním všech možných stavů povolení.
Na iOS se žádost provádí přes metodu requestAccess třídy CNContactStore. Výsledek je vrácen v closure s logickou hodnotou a volitelnou chybou. Níže uvedený příklad demonstruje úplný cyklus žádosti se zpracováním stavu.
import Contacts
let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
if granted {
print("Přístup ke kontaktům získán")
// Provádění operací s kontakty
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
try? store.enumerateContacts(with: request) { contact, stop in
print("\(contact.givenName) \(contact.familyName)")
}
} else {
print("Přístup odmítnut: \(error?.localizedDescription ?? "neznámá chyba")")
}
}
Na Androidu se žádost provádí přes ActivityResultLauncher s kontraktem RequestPermission. Níže uvedený příklad ukazuje práci s ContactsContract.ContentProvider po získání povolení.
val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
val uri = ContactsContract.Contacts.CONTENT_URI
val cursor = contentResolver.query(uri, null, null, null, null)
cursor?.use {
val nameIndex = it.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
while (it.moveToNext()) {
val name = it.getString(nameIndex)
Log.d("Contacts", "Contact: $name")
}
}
} else {
// Vysvětlení uživateli důvodu potřeby přístupu
showRationaleDialog()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissionLauncher.launch(android.Manifest.permission.READ_CONTACTS)
}
Zkušení vývojáři mobilních aplikací dodržují sadu osvědčených postupů při práci s povolením přístupu ke kontaktům. Tato pravidla pomáhají projít moderací obchodů s aplikacemi a udržet důvěru uživatelů. Dodržování nejlepších postupů výrazně zjednodušuje proces publikace a údržby aplikace.
Nikdy nežádejte o přístup ke kontaktům při prvním spuštění aplikace. První žádost by měla nastat v kontextu konkrétní funkce: vyhledávání přátel, zvaní účastníků, import kontaktů. Uživatel, který rozumí důvodu žádosti, souhlasí 2-3krát častěji, jak ukazuje výzkum Apptentive (2024).
Pokud funkčnost stačí pro přístup k jednomu kontaktu — použijte CNContactPickerViewController na iOS nebo implicit intent ACTION_PICK na Androidu. Tyto metody nevyžadují předchozí povolení a umožňují uživateli samostatně vybrat záznam bez odhalení celého adresáře aplikaci.
Aplikace musí správně zpracovat situaci, kdy uživatel žádost odmítl. Na iOS zkontrolujte stav přes CNContactStore.authorizationStatus(for:) a v případě potřeby nasměrujte uživatele do Nastavení. Na Androidu použijte shouldShowRequestPermissionRationale pro zobrazení dodatečného vysvětlení před opětovnou žádostí.
Nikdy nezobrazujte opakovaný dialog ihned po odmítnutí — je to vnímáno jako agrese a snižuje hodnocení aplikace. Nejlepší postup: po určité době zobrazte obrazovku s vysvětlením a tlačítkem „Přejít do nastavení”, které otevře systémovou obrazovku povolení přes Intent. Testujte scénář odmítnutí na reálných zařízeních — simulátory ne vždy správně reprodukují chování systémových dialogů povolení.
Často kladené otázky
Aplikace žádají o přístup ke kontaktům pro funkce jako vyhledávání přátel, zvaní účastníků, automatické vyplňování formulářů a synchronizaci s serverem. Příklady: messengery hledají kontakty podle telefonního čísla, CRM aplikace importují klienty.
Jednorázový přístup (iOS 17+) přes CNContactPickerViewController umožňuje uživateli vybrat jeden kontakt bez odhalení celého adresáře. Plný přístup umožňuje aplikaci číst všechny kontakty zařízení přes CNContactStore. Jednorázový přístup je bezpečnější a nevyžaduje uvedení NSContactsUsageDescription v privacy manifestu.
Na iOS přejděte do Nastavení — Soukromí a zabezpečení — Kontakty a vypněte přístup pro konkrétní aplikaci. Na Androidu otevřete Nastavení — Aplikace — vyberte aplikaci — Oprávnění — Kontakty a zvolte „Odmítnout”.
Privacy Manifest (soubor privacy.xcprivacy) — povinný dokument pro iOS 18+, ve kterém vývojář deklaruje důvody přístupu k chráněným datům, včetně kontaktů. Klíč NSContactsUsageDescription obsahuje lokalizovaný popis zobrazený v systémovém dialogu žádosti o povolení.
Android klasifikuje READ_CONTACTS jako nebezpečné povolení (dangerous permission), protože poskytuje přístup k osobním údajům uživatele. Mechanismus runtime permissions, zavedený v Android 6.0, vyžaduje výslovný souhlas za běhu, nejen při instalaci aplikace.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také