In Own storage mode, Agendula now publishes its Room store as a ContentProvider that follows the OpenTasks contract. It serves `tasklists`, `tasks`, `instances` and `properties` (reminders and tags) at `<package>.tasks`, behind a dangerous-level `<package>.permission.READ_TASKS` that the user grants per app. An app that already reads OpenTasks or tasks.org only has to change the authority and the permission. On a query, the provider lays the Room store out in OpenTasks' columns and loads that into an in-memory SQLite database, so a client's selection, arguments and sort order run as real SQL. The snapshot is rebuilt after a write, after a storage mode switch, or once it is an hour old, because instance ids and `distance_from_current` move with the clock. Observers on the authority get one notification per burst of changes. In External mode every table is empty. Recurrence expansion moved out of `RoomTasksDataSource` into shared functions, so the app and the provider expand a series the same way. `docs/CONTENT_PROVIDER.md` describes the contract for client developers, with the authority and permission for each build. README, CHANGELOG and the privacy policy mention the new permission. Where this differs from the issue: the issue asked for read and write permissions, and this PR is read-only. Insert, update and delete throw. Accepting writes from other apps means deciding what happens to the fields Agendula keeps verbatim for CalDAV round-tripping, which was the issue's second open question, and that needs its own design. That is tracked in #63. Closes #43 Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de> Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/62
2.9 KiB
2.9 KiB
Reading Agendula's tasks from another app
When Agendula keeps tasks in its own database (the default storage mode), it
publishes them through a read-only ContentProvider that follows the
OpenTasks contract.
An app that already reads OpenTasks or tasks.org can read Agendula by using a
different authority and permission.
| Authority | de.jeanlucmakiola.agendula.tasks (offline build: de.jeanlucmakiola.agendula.offline.tasks) |
| Permission | de.jeanlucmakiola.agendula.permission.READ_TASKS (offline build: de.jeanlucmakiola.agendula.offline.permission.READ_TASKS) |
| Protection level | dangerous: request it at runtime |
| Package visibility | add <provider android:authorities="de.jeanlucmakiola.agendula.tasks" /> to your <queries> |
Both names are derived from the installed package name, so every build has its
own and they can be installed side by side: the authority is
<package>.tasks and the permission <package>.permission.READ_TASKS.
| Build | Package |
|---|---|
| Release | de.jeanlucmakiola.agendula |
| Release, offline | de.jeanlucmakiola.agendula.offline |
| Debug | de.jeanlucmakiola.agendula.debug |
| Debug, offline | de.jeanlucmakiola.agendula.offline.debug |
| Release test | de.jeanlucmakiola.agendula.releasetest |
| Release test, offline | de.jeanlucmakiola.agendula.offline.releasetest |
Tables
| URI | Rows |
|---|---|
content://<authority>/tasklists |
one per list |
content://<authority>/tasks |
one per task; a modified occurrence of a recurring task is its own row with original_instance_id / original_instance_time set |
content://<authority>/instances |
one per occurrence: recurring tasks are expanded up to one year back and two years ahead, and modified occurrences replace the ones they override |
content://<authority>/properties |
reminders (vnd.android.cursor.item/alarm) and tags (vnd.android.cursor.item/category) |
Each table also accepts /<id>. Column names, value encodings (epoch millis,
all-day dates as UTC midnight, status, priority, class) and MIME types
are the OpenTasks ones. selection, selectionArgs and sortOrder work as
they do against OpenTasks.
Behaviour
- Read-only.
insert,updateanddeletethrowUnsupportedOperationException. - Change notifications. Register a
ContentObserveroncontent://<authority>withnotifyForDescendants = true. It fires when tasks change or when the user switches storage mode. - External storage mode. When the user has Agendula work on top of OpenTasks or tasks.org, every table is empty. Read that provider directly.
- Instance ids are not stable: as in OpenTasks they are reassigned when the
data changes, and also hourly as the expansion window moves (observers are
notified then too). Key on
task_idplusinstance_original_time.