Skip to content

ahnafnafee/pinned-calendar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pinned Calendar

Your week's Google Calendar events and to-dos in a single persistent Android notification.

Platform Min SDK Kotlin Jetpack Compose License: MIT Latest release


Pinned Calendar is an open-source Android app that keeps this week's Google Calendar events and your to-dos in one ongoing notification at the top of the shade. It reads the calendars already synced on your device, so there is no Google sign-in, no OAuth, and no internet permission β€” your schedule never leaves the phone.

The pin is self-healing: swipe it away by accident and it re-posts itself. When you do want it gone, switch it off in the app or turn on swipe-twice-to-remove.

Screenshots

Pinned agenda (light) Pinned agenda (dark) To-dos tab Settings tab
Persistent calendar notification showing the week's agenda in light mode Persistent calendar notification showing the week's agenda in dark mode To-dos tab with the week overview card and task list Settings tab with Material You cards for notifications, time window, and calendars

Features

  • Persistent, self-healing notification: an ongoing pin that re-posts itself after an accidental swipe. Set its priority to Top, Normal, or Silent β€” Top keeps it above your everyday notifications without ever popping up or making a sound.
  • Swipe twice to remove: an optional gesture to dismiss the pin for good without opening settings.
  • Reads your device calendars through Android's Calendar Provider, with per-calendar colours. No sign-in, no OAuth, no network.
  • Local to-dos: add quick tasks in the app and they merge into the same agenda. Tasks carry forward day to day until you complete or delete them.
  • Day-grouped agenda: Today, Tomorrow, and weekday sections, color-coded per calendar, with tasks shown as their own rows.
  • Tap an event row to open it directly in Google Calendar; tap anywhere else on the pin to jump into the app.
  • Material 3 and Material You: wallpaper-based dynamic colour, seed colours, palette styles, AMOLED black, and selectable fonts.
  • Light, dark, and system themes, plus a theme- and accent-adaptive launcher icon.
  • Configurable window: the next 3 days, this week, 7 days, or 14 days. Choose which calendars appear and cap the item count.
  • Background refresh with WorkManager and a ContentObserver for instant updates, plus an optional battery-optimization exemption for aggressive OEMs.
  • No foreground service, so it stays light on battery; the pin restores itself after reboots and app updates.
  • Offline by design: no analytics, no accounts, and minimal permissions.

Privacy and permissions

Pinned Calendar is offline-first. It has no INTERNET permission and sends nothing off the device.

Permission Why it's needed
READ_CALENDAR Read the events already synced on your device.
POST_NOTIFICATIONS Show the pinned agenda (Android 13+).
RECEIVE_BOOT_COMPLETED Re-pin the agenda after a reboot.
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Optional β€” keep background refresh reliable on aggressive devices.

No accounts, ads, trackers, or cloud.

Tech stack

Area Technology
Language Kotlin 2.2
UI Jetpack Compose Β· Material 3
Dynamic colour MaterialKolor Β· Material You
Background work WorkManager Β· ContentObserver
Storage DataStore (Preferences)
Calendar CalendarContract (Calendar Provider)
Notification NotificationCompat Β· custom RemoteViews
Build AGP 9.2 Β· Gradle 9.5 Β· compileSdk 36 Β· minSdk 26

Download

Download the latest signed APK from the Releases page and install it on your device. You may need to allow installs from unknown sources. No Play Store account is required.

Building from source

Prerequisites: Android Studio (latest), JDK 17+, and Android SDK Platform 36.

git clone https://github.com/ahnafnafee/pinned-calendar.git
cd pinned-calendar
./gradlew :app:assembleDebug          # build a debug APK
./gradlew :app:installDebug           # install on a connected device/emulator

Or open the project in Android Studio and run it. On first launch, grant Calendar and Notification access, then turn on "Pin to notifications". For reliable background updates on aggressive OEMs, also enable "Ignore battery optimizations" under Reliability.

How it works

Device Calendar Provider ─┐
                          β”œβ”€β–Ί AgendaRepository ─► NotificationContentBuilder ─► ongoing notification
Local to-dos (DataStore) β”€β”˜            β–²                                              β”‚ deleteIntent
                                       β”‚                                              β–Ό
              WorkManager (15-min refresh) + ContentObserver        SelfHealReceiver re-posts on swipe

A pure-Kotlin core (windowing, day-bucketing, content building) is unit-tested and decoupled from Android, and the platform layer (RemoteViews, WorkManager, receivers) consumes it. There is no foreground service: the notification persists on its own, and a delete-intent receiver makes it self-healing.

Configuration

The app is split into two tabs.

To-dos β€” the week at a glance:

  • Week overview card β€” how many items are pinned, day by day.
  • Add, complete, and delete local to-dos that merge into the pinned agenda.

Settings β€” everything else, Material You styled:

  • Notifications β€” pin on/off, priority (Top Β· Normal Β· Silent), and optional swipe-twice-to-remove. Top keeps the pin above your everyday notifications.
  • Time window β€” 3 days Β· this week Β· 7 days Β· 14 days.
  • Calendars β€” toggle each synced calendar on or off.
  • Display β€” group by day, hide completed to-dos, and a max-items cap.
  • Appearance β€” theme, Material You, AMOLED, accent seed, palette style, and font.
  • Reliability β€” battery-optimization exemption.

Roadmap

  • Full colour-picker for custom seed colours
  • Home-screen widget companion
  • Per-to-do due-date picker
  • Google Tasks integration (opt-in)
  • Recurring-task support
  • Wear OS tile

Have an idea? Open an issue.

Contributing

Contributions are welcome. Fork the repo, create a feature branch, run ./gradlew :app:testDebugUnitTest, and open a pull request. For larger changes, open an issue first to discuss the approach.

License

Released under the MIT License. See LICENSE.

Acknowledgements

  • MaterialKolor for seed-based Material You theming.
  • The bundled fonts (Figtree, Outfit, Inter, Google Sans Flex) and the Material 3 design system.

About

πŸ“Œ Privacy-first Android app that pins your week's Google Calendar events + to-dos to the notification shade β€” self-healing, 100% local, Material You. Kotlin + Jetpack Compose.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages