feat(contacts): declare READ_CONTACTS + read contact special-dates
Codeberg #15, foundation for the contact special-dates calendars. Declares the optional, feature-gated READ_CONTACTS permission (never requested at startup) and adds the offline, read-only contacts reader. - AndroidManifest: READ_CONTACTS with a comment documenting the opt-in/offline one-way-mirror contract. - domain/contacts: SpecialDateType + ContactSpecialDate model and a pure parseContactEventDate covering full (yyyy-MM-dd), year-less (--MM-dd) and compact (yyyyMMdd) shapes, with Feb-29 handling via a leap anchor. - data/contacts: ContactSpecialDatesDataSource querying ContactsContract.Data Event rows, split by TYPE, deduped per (contact, type); returns empty without the permission so sync can degrade to a stalled state. Hilt-bound. - Unit tests for the date parser (full/year-less/compact/Feb-29/malformed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,15 @@
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!--
|
||||
Optional and feature-gated: only the "Contact special dates" feature reads
|
||||
contacts, and only after the user enables it and grants this at runtime
|
||||
(never requested at startup). Everything stays offline — birthdays and
|
||||
other contact dates are mirrored one-way into local calendars; contacts
|
||||
are never written and nothing leaves the device (the app has no INTERNET
|
||||
permission). See docs/design/contact-special-dates.md.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<!--
|
||||
Lets the "Reliable delivery" setting open the direct system dialog to
|
||||
exempt Calendula from battery optimisation (so reminder broadcasts aren't
|
||||
|
||||
Reference in New Issue
Block a user