Oprávnění přístupu ke kalendáři je mechanismus mobilních operačních systémů, který chrání kalendářní data uživatele před neoprávněným čtením a úpravou. V iOS je přístup ke kalendáři realizován prostřednictvím frameworku EventKit s třídami EKEventStore a EKCalendar, na Androidu pak prostřednictvím oprávnění READ_CALENDAR a WRITE_CALENDAR ve spojení s CalendarContract API. Podle Apple Developer Documentation, 2025, pro přístup ke kalendáři v iOS 18+ je vyžadována výslovná žádost prostřednictvím systémového dialogu. EventKit poskytuje jednotné rozhraní pro čtení a vytváření událostí ve všech připojených kalendářích.
Hlavní body
Oprávnění přístupu ke kalendáři je mechanismus ochrany osobních údajů, který řídí čtení a zápis událostí v aplikacích kalendáře zařízení. Kalendář obsahuje důvěrné informace: schůzky, termíny, připomínky a osobní plány uživatele, proto mobilní operační systémy klasifikují přístup k němu jako kritický.
Na iOS je přístup ke kalendáři regulován frameworkem EventKit. Aplikace může požádat o přístup pro čtení a zápis událostí a uživatel může žádost přijmout nebo odmítnout prostřednictvím systémového dialogu. Na Androidu je ochrana založena na dvou oprávněních za běhu: READ_CALENDAR a WRITE_CALENDAR.
Podle výzkumu Pew Research Center (2024) přibližně 45% uživatelů mobilních zařízení pravidelně používá kalendář a 62% z nich odmítá přístup aplikacím, které nevysvětlují důvod žádosti o kalendářní data.
Klíčový princip — aplikace by měla žádat o přístup pouze pro funkce, které přímo souvisejí s kalendářem: vytváření připomínek, synchronizace událostí, import rozvrhu.
Na iOS je přístup ke kalendáři a připomínkám zajištěn jediným frameworkem EventKit. Centrální třída EKEventStore spravuje všechny operace: žádost o oprávnění, čtení událostí, vytváření a úpravu záznamů v kalendáři. Při prvním zavolání requestAccess(to:entityType:) systém zobrazí nativní dialog s vysvětlením.
Třída EKEventStore je vstupním bodem do subsystému kalendáře iOS. Pro žádost o přístup je třeba zavolat metodu requestAccess(to: .event) s předáním typu entity (událost nebo připomínka). Po získání oprávnění poskytuje EKEventStore přístup ke všem kalendářům připojeným k účtům iCloud, Google, Exchange a dalších poskytovatelů.
Důležitá vlastnost: EKEventStore je těžký objekt, jeho vytvoření zabírá čas a spotřebovává zdroje. Doporučuje se inicializovat jej jednou a znovu používat po dobu životního cyklu aplikace. Podle WWDC Session 10117 (2024) Apple doporučuje ukládat instanci EventStore do mezipaměti pro optimalizaci výkonu.
iOS nerozlišuje oprávnění pro čtení a zápis kalendáře — uživatel poskytne buď plný přístup, nebo odmítne. Aplikace však může řídit operace na úrovni kódu: čtení událostí prostřednictvím EKEventStore.event, vytváření prostřednictvím EKEventStore.save a mazání prostřednictvím EKEventStore.remove. Od iOS 18 se objevila možnost žádat o přístup pouze k určitému typu entity — .event nebo .reminder.
V iOS 17+ Apple představil mechanismus dočasného přístupu: některé aplikace mohou získat přístup na 24 hodin po jednorázovém potvrzení uživatelem. Tato funkce je užitečná zejména pro aplikace, které potřebují kalendář jen jednou — například pro import rozvrhu konference.
Na Androidu je přístup ke kalendáři chráněn dvěma samostatnými oprávněními: READ_CALENDAR a WRITE_CALENDAR. Obě patří do kategorie nebezpečných a vyžadují žádost za běhu. Oddělení čtení od zápisu umožňuje uživateli jemně nastavit úroveň přístupu aplikace.
Oprávnění READ_CALENDAR dává aplikaci možnost číst události ze všech kalendářů uživatele, včetně názvů, času, účastníků a popisu. Oprávnění WRITE_CALENDAR umožňuje vytvářet, měnit a mazat události. Obě jsou specifikována v manifestu pomocí tagu uses-permission a jsou žádána za běhu prostřednictvím ActivityResultLauncher.
Počínaje Androidem 14 (API 34) systém varuje uživatele, pokud aplikace žádá obě oprávnění současně. Doporučuje se žádat je odděleně: nejprve READ_CALENDAR pro čtení, poté WRITE_CALENDAR při prvním pokusu o vytvoření události. Podle Google I/O 2024 tento přístup snižuje míru odmítnutí o 23%.
CalendarContract je ContentProvider Androidu, který strukturalizuje kalendářní data do relačních tabulek. Hlavní tabulky: Calendars (seznam kalendářů), Events (události), Attendees (účastníci), Reminders (připomínky). Přístup k datům se provádí prostřednictvím ContentResolver.query() s uvedením URI a projekce.
Pro vložení nové události je třeba použít ContentValues s uvedením kalendáře, času začátku a konce, názvu a popisu. CalendarContract podporuje časová pásma, opakující se události a připomínky s konfigurovatelným intervalem upozornění.
Implementace žádosti o přístup ke kalendáři vyžaduje zohlednění platformních charakteristik. Níže jsou uvedeny příklady v Swift a Kotlin, které demonstrují správnou práci s EventKit a CalendarContract.
Žádost o přístup ke kalendáři iOS se provádí prostřednictvím metody requestAccess třídy EKEventStore. Níže uvedený příklad ukazuje vytvoření události po získání oprávnění.
import EventKit
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event) { granted, error in
guard granted else {
print("Přístup ke kalendáři odmítnut")
return
}
let event = EKEvent(eventStore: eventStore)
event.title = "Týmová schůzka"
event.startDate = Date()
event.endDate = Date(timeIntervalSinceNow: 3600)
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
print("Událost vytvořena: \(event.eventIdentifier)")
} catch {
print("Chyba ukládání: \(error.localizedDescription)")
}
}
Na Androidu se žádost o oprávnění READ_CALENDAR a WRITE_CALENDAR provádí prostřednictvím ActivityResultLauncher. Příklad ukazuje čtení událostí z kalendáře uživatele po získání přístupu.
val calendarPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions[Manifest.permission.READ_CALENDAR] == true) {
val uri = CalendarContract.Events.CONTENT_URI
val projection = arrayOf(
CalendarContract.Events.TITLE,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND
)
val cursor = contentResolver.query(uri, projection, null, null, null)
cursor?.use {
val titleIndex = it.getColumnIndex(CalendarContract.Events.TITLE)
while (it.moveToNext()) {
Log.d("Calendar", "Událost: ${it.getString(titleIndex)}")
}
}
} else {
// Zobrazit vysvětlení a nabídnout přechod do nastavení
requestPermissionSettingsRedirect()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
calendarPermissionLauncher.launch(
arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)
)
}
Práce s oprávněními kalendáře vyžaduje promyšlenou strategii, která zohledňuje požadavky obou platforem a očekávání uživatelů. Dodržování následujících doporučení pomáhá projít moderací a zvýšit míru poskytování přístupu.
Žádejte o přístup ke kalendáři pouze v okamžiku, kdy uživatel provádí akci vyžadující kalendářní data: „Přidat do kalendáře”, „Synchronizovat rozvrh”, „Importovat události”. Předběžné vysvětlení pomocí dialogu před oprávněním (vlastní dialog před systémovým) zvyšuje míru souhlasu o 35%, podle Localytics (2024).
Na iOS použijte klíč NSCalendarsUsageDescription v privacy manifestu s konkrétním textem. Místo „Pro vytváření událostí” napište „Pro přidávání tréninků do vašeho kalendáře”. Konkrétní formulace zvyšuje konverzi žádosti o 20–30%.
Pokud uživatel žádost odmítl, nezobrazujte znovu systémový dialog — to povede k aktivaci neverAskAgain na Androidu nebo nedostupnosti dialogu na iOS. Místo toho navrhněte přechod do nastavení pomocí Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) na Androidu nebo UIApplication.openSettingsURLString na iOS.
Při opětovném vstupu na obrazovku zkontrolujte stav oprávnění. Na iOS zavolejte EKEventStore.authorizationStatus(for: .event) a aktualizujte UI podle aktuálního stavu. Na Androidu použijte ContextCompat.checkSelfPermission() pro kontrolu aktuálního stavu a rozhodnutí o zobrazení tlačítka přesměrování do nastavení.
Často kladené otázky
Aplikace žádají o přístup ke kalendáři pro vytváření událostí, synchronizaci rozvrhu, import termínů a integraci s připomínkami. Příklady: fitness trackery přidávají tréninky, plánovače vytvářejí úkoly a cestovní aplikace importují lety do kalendáře uživatele.
READ_CALENDAR poskytuje přístup ke čtení všech událostí a kalendářů uživatele. WRITE_CALENDAR umožňuje vytvářet, měnit a mazat události. Uživatel může poskytnout jedno oprávnění bez druhého, což poskytuje flexibilní kontrolu nad úrovní přístupu aplikace ke kalendářním datům.
Otevřete Nastavení — Soukromí a bezpečnost — Kalendáře. Vyberte aplikaci a vypněte přepínač přístupu. Aplikace ztratí možnost číst a vytvářet události do další výslovné žádosti a potvrzení uživatelem.
Aplikace nebude moci číst ani vytvářet události. Metoda requestAccess vrátí granted = false na iOS nebo checkSelfPermission vrátí PERMISSION_DENIED na Androidu. Vývojář by měl zajistit graceful degradation — aplikace nadále funguje bez funkcí kalendáře, bez pádů nebo zobrazování chyb.
Na iOS taková možnost neexistuje — EventKit vyžaduje úplný přístup pro jakékoli operace s událostmi. Na Androidu můžete použít Intent.ACTION_INSERT k vytvoření události prostřednictvím systémové aplikace kalendáře, což nevyžaduje oprávnění za běhu, ale ani neumožňuje čtení existujících událostí.
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é