Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Renovate / renovate (push) Successful in 54s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 21m44s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 55s
Agendula 1.1.0. Merging this triggers the release pipeline (F-Droid, Codeberg, Play) and mints the v1.1.0 tag. - Tags, synced as CATEGORIES (#35) - Saved filters, also usable in the Tasks widget (#47) - Offline flavor without sync or network, published to Codeberg only (#39) - New Today, Up next, Lists and Week widgets; widgets can show several lists - Synced lists can be renamed and deleted - All-day tasks no longer land a day off west of UTC in smart lists and filters versionName 1.1.0 / versionCode 1010099. CHANGELOG has the 1.1.0 section, and What's New is written for en-US, en-GB, de-DE, pt-BR, plus new fr-FR and ar. After the tag lands, fdroiddata!49998 needs a 1.1.0 build entry with gradle: full. Closes #35, closes #39, closes #47 Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de> Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/51
263 lines
12 KiB
XML
263 lines
12 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. Agendula publishes no ContentProvider and declares no
|
|
permissions of its own. -->
|
|
<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" />
|
|
|
|
<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: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">
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.MAIN" />
|
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
</intent-filter>
|
|
<!-- 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>
|
|
|
|
<!-- 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>
|
|
|
|
<!-- 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>
|