Files
agendula/app/src/main/AndroidManifest.xml
T
Jean-Luc Makiolaandmakiolaj 7bcac70cec
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 8s
Renovate / renovate (push) Successful in 1m7s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 18m49s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 1m34s
Beta — Codeberg pre-release / detect (push) Successful in 4s
Beta — Codeberg pre-release / beta (push) Skipped
Release 1.3.0 (#134)
Stable 1.3.0, after 1.3.0-beta.1 and beta.2.

- Version bumped to 1.3.0 (1030099); the CHANGELOG entries moved from Unreleased to 1.3.0.
- What's New for every shipped locale, now including ru-RU, which also gets its full store listing. values-uk and values-zh-rCN came in empty from Weblate, so they get no store locale yet.
- fr, ar, cs and ru added to locales_config.xml, so they show up in the in-app language picker and Android's per-app language settings. Before, only en, de and pt-BR did.
- `main` (Weblate #87) merged in, no conflicts and no stale keys.
- Lint has failed on this branch since #113: `NavController.currentBackStack` is a RestrictedApi. It's suppressed at that one call, since no public API exposes the whole back stack and `visibleEntries` drops an entry once another one covers it.

#119, #121, #122/#123 and #127/#129 landed after beta.2, so no tester has seen them yet.

Closes #68, closes #73, closes #90, closes #91, closes #93, closes #94, closes #99, closes #104, closes #105, closes #119, closes #121, closes #122, closes #123, closes #127, closes #129

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/134
2026-11-02 21:26:15 +01:00

311 lines
14 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- External tasks-provider access, for StorageMode.EXTERNAL only. Both
permission sets are declared, since the manifest is static; the active one
(org.tasks.* for tasks.org, org.dmfs.* for OpenTasks) is requested at
runtime by the permission flow, and only once the user has actually
selected External mode. Both are dangerous-level.
StorageMode.OWN needs nothing here: it is a Room database in our own data
directory. -->
<uses-permission android:name="org.dmfs.permission.READ_TASKS" />
<uses-permission android:name="org.dmfs.permission.WRITE_TASKS" />
<uses-permission android:name="org.tasks.permission.READ_TASKS" />
<uses-permission android:name="org.tasks.permission.WRITE_TASKS" />
<!-- What another app requests to read or write the own store through
AgendulaTaskProvider. Dangerous, like OpenTasks' own: the user grants
them per app. Suffixed per build, so debug and release can coexist. -->
<permission
android:name="${applicationId}.permission.READ_TASKS"
android:description="@string/permission_read_tasks_description"
android:label="@string/permission_read_tasks_label"
android:protectionLevel="dangerous" />
<permission
android:name="${applicationId}.permission.WRITE_TASKS"
android:description="@string/permission_write_tasks_description"
android:label="@string/permission_write_tasks_label"
android:protectionLevel="dangerous" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Exact due-time reminders. User-granted: USE_EXACT_ALARM is reserved for
alarm-clock and calendar apps on Play. Without it reminders go inexact. -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!-- Package visibility (Android 11+): see the tasks providers so
resolveContentProvider works, and launchable apps so we can open the
provider / a store listing during onboarding. -->
<queries>
<provider android:authorities="org.dmfs.tasks" />
<provider android:authorities="org.tasks.opentasks" />
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
<application
android:name=".AgendulaApp"
android:allowBackup="true"
android:enableOnBackInvokedCallback="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Agendula"
tools:targetApi="35">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize">
<!-- MAIN/LAUNCHER lives on the two aliases below, so the launcher
name can be switched at runtime (#104). -->
<!-- Shared text becomes a new task's title. -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<!-- An .ics opened or shared from another app goes to the import screen. -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content" />
<data android:mimeType="text/calendar" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/calendar" />
</intent-filter>
</activity>
<activity-alias
android:name=".DefaultNameAlias"
android:enabled="true"
android:exported="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".TasksNameAlias"
android:enabled="false"
android:exported="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name_tasks_alias"
android:roundIcon="@mipmap/ic_launcher_round"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- Quick Settings "New task" tile. Only the system QS host can bind it. -->
<service
android:name=".qs.NewTaskTileService"
android:exported="true"
android:icon="@drawable/ic_qs_new_task"
android:label="@string/qs_tile_new_task"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<!-- Standalone crash-report surface; MainActivity routes here on a
startup crash-loop. Not exported, kept out of recents. -->
<activity
android:name=".ui.crash.CrashReportActivity"
android:exported="false"
android:excludeFromRecents="true"
android:launchMode="singleTask" />
<!-- Reminder alarm fires here (internal PendingIntent → not exported). -->
<receiver
android:name=".data.reminders.DueReminderReceiver"
android:exported="false" />
<!-- Done / Snooze on a reminder, and the snooze re-show (internal). -->
<receiver
android:name=".data.reminders.ReminderActionReceiver"
android:exported="false" />
<!-- Re-arm alarms after reboot, an update, a clock/zone change, or an exact-alarm grant. -->
<receiver
android:name=".data.reminders.BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
</intent-filter>
</receiver>
<!-- Re-sync reminders when an external provider changes — DAVx5 pulling
tasks while Agendula is backgrounded. External mode only: in OWN mode
nothing outside the app can change our data, and Room's
InvalidationTracker covers our own writes.
An intent-filter host must be a literal, so both external authorities
are listed — one filter each. Two <data> tags in a single filter would
mean the same thing (Android takes the cross product of every data
attribute in a filter), but reads as if it might not, which is what
lint's IntentFilterUniqueDataAttributes warns about. -->
<receiver
android:name=".data.reminders.ProviderChangeReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED" />
<data android:scheme="content" android:host="org.dmfs.tasks" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED" />
<data android:scheme="content" android:host="org.tasks.opentasks" />
</intent-filter>
</receiver>
<!-- Home-screen task widget (Glance). Exported: the launcher binds it. -->
<receiver
android:name=".widget.TaskWidgetReceiver"
android:label="@string/widget_tasks_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info_tasks" />
</receiver>
<!-- "Today" home-screen widget (Glance): a progress ring for today's tasks. -->
<receiver
android:name=".widget.TodayWidgetReceiver"
android:label="@string/widget_today_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info_today" />
</receiver>
<!-- "Up next" home-screen widget (Glance): the single nearest due task. -->
<receiver
android:name=".widget.UpNextWidgetReceiver"
android:label="@string/widget_up_next_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info_up_next" />
</receiver>
<!-- "Lists" home-screen widget (Glance): one shortcut tile per list. -->
<receiver
android:name=".widget.ListsWidgetReceiver"
android:label="@string/widget_lists_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info_lists" />
</receiver>
<!-- "Week" home-screen widget (Glance): a seven-day strip of task counts. -->
<receiver
android:name=".widget.WeekWidgetReceiver"
android:label="@string/widget_week_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info_week" />
</receiver>
<!-- Per-widget list picker, launched by the host on placement / reconfigure. -->
<activity
android:name=".widget.TaskWidgetConfigActivity"
android:exported="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<!-- Redraws the widget on the day boundary (the app's own ROLLOVER alarm,
sent by explicit PendingIntent) and on a language change; the rest
re-arm that alarm. Task changes are handled in-process instead. -->
<receiver
android:name=".widget.WidgetUpdateReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
<!-- The own store under the OpenTasks contract. Empty, and refusing
writes, while External mode is active. -->
<provider
android:name=".data.tasks.provider.AgendulaTaskProvider"
android:authorities="${applicationId}.tasks"
android:exported="true"
android:readPermission="${applicationId}.permission.READ_TASKS"
android:writePermission="${applicationId}.permission.WRITE_TASKS"
tools:ignore="SystemPermissionTypo" />
<!-- WorkManager's on-demand initialisation. Removing the default
initializer is what lets AgendulaApp supply a HiltWorkerFactory, so
@HiltWorker workers can take injected dependencies. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
<!-- Persists the per-app language on API < 33, where the platform
per-app-languages API is unavailable. On 33+ this is a no-op. -->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
</application>
</manifest>