- datenschutz.astro: DSGVO privacy policy (server logfiles, Hetzner as Auftragsverarbeiter per Art. 28, cookieless Umami, self-hosted fonts, data-subject rights, supervisory-authority complaint). - consts.ts: extract shared LEGAL entity data; Impressum now reads from it. - blog: "Why my calendar app has no internet permission" and "Open standards as a constraint, not a checkbox". - uses.astro: colophon of the site stack, Floret apps, and self-hosted infra. - Footer: add Uses + Datenschutz links alongside Impressum. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
68 lines
3.3 KiB
Markdown
68 lines
3.3 KiB
Markdown
---
|
|
title: Why my calendar app has no internet permission
|
|
description: >-
|
|
Calendula can't talk to the network — and that's the whole design. A look at
|
|
building on Android's CalendarContract instead of reinventing a sync stack.
|
|
pubDate: 2026-06-28
|
|
tags: [android, architecture, calendula]
|
|
draft: false
|
|
---
|
|
|
|
Open Calendula's manifest and you'll notice something missing: there is no
|
|
`android.permission.INTERNET`. The app physically *cannot* reach the network.
|
|
For a calendar — a category of app practically synonymous with cloud accounts —
|
|
that sounds like a missing feature. It's the opposite. It's the design.
|
|
|
|
## The usual shape of a calendar app
|
|
|
|
Most calendar apps own their data. They sign you into an account, pull events
|
|
down over the provider's API, cache them in a private database, and reconcile
|
|
changes with their own sync engine. That sync stack is the hard part: conflict
|
|
resolution, recurring-event expansion, time zones, retries, token refresh. It's
|
|
also the part that locks you in — your events live in *their* schema, reachable
|
|
only through *their* app.
|
|
|
|
## The other option Android already gives you
|
|
|
|
Android ships a system calendar database, exposed through
|
|
[`CalendarContract`](https://developer.android.com/reference/android/provider/CalendarContract).
|
|
Anything synced to your device lands there: a CalDAV account via
|
|
[DAVx5](https://www.davx5.com/), your Google calendar, a local on-device
|
|
calendar, a read-only WebCal subscription. They all show up through the same
|
|
content provider, with the same columns.
|
|
|
|
Calendula is a pure front-end over that provider. It reads events through
|
|
`CalendarContract`, and when you create or edit something, it writes straight
|
|
back. Whatever sync adapter put the calendar on your device picks the change up
|
|
and pushes it out. There is **no own database and no reinvented sync stack** —
|
|
so there is nothing for the app to phone home about.
|
|
|
|
## What you get for free
|
|
|
|
Dropping the network permission isn't a sacrifice; it's what falls out of the
|
|
architecture:
|
|
|
|
- **Your data stays yours, and stays portable.** Events live in the platform's
|
|
store and in your CalDAV account — not in a schema only Calendula understands.
|
|
- **Privacy is structural, not a promise.** Zero telemetry and zero analytics
|
|
are easy to claim. *No internet permission* is enforced by the OS: even if I
|
|
wanted to exfiltrate your schedule, the app couldn't.
|
|
- **Reminders still work** — Calendula delivers them itself as notifications,
|
|
because Android delegates reminder delivery to the installed calendar app.
|
|
- **Any account "just appears."** Add a new CalDAV account in DAVx5 and it
|
|
surfaces in Calendula with no integration work, because the integration point
|
|
is the OS, not a vendor API.
|
|
|
|
## The trade-off, stated honestly
|
|
|
|
A front-end can only be as good as the provider beneath it. Calendula doesn't
|
|
add its own server-side features, and it relies on a sync adapter like DAVx5
|
|
being installed to actually move bytes. That's a deliberate line: I'd rather put
|
|
a thoughtful Material 3 Expressive interface on an open protocol than own a sync
|
|
stack I'd inevitably get subtly wrong.
|
|
|
|
The same idea drives the rest of the [Floret family](/work) — Agendula is the
|
|
exact same bet, made on the OpenTasks provider instead of the calendar one.
|
|
Different content, identical philosophy: build the part that's worth building,
|
|
and let open standards carry the rest.
|