├── app ├── .gitignore ├── src │ ├── test │ │ ├── resources │ │ │ ├── backup_unknown_version.json │ │ │ ├── backup_minified.json │ │ │ ├── backup_incomplete_data.json │ │ │ └── backup.json │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── fi3te │ │ │ └── notificationcron │ │ │ ├── ui │ │ │ └── NotificationServiceTest.kt │ │ │ └── data │ │ │ ├── DateTimeServiceTest.kt │ │ │ └── remote │ │ │ └── BackupJsonServiceTest.kt │ ├── main │ │ ├── assets │ │ │ ├── images │ │ │ │ ├── icon.png │ │ │ │ ├── app_icon_base.png │ │ │ │ ├── app_icon_background.png │ │ │ │ └── app_icon_base.svg │ │ │ └── copy_of_apache_license.txt │ │ ├── res │ │ │ ├── drawable │ │ │ │ ├── notification_icon.png │ │ │ │ ├── ic_more_vert_grey_600_24dp.xml │ │ │ │ └── ic_add_alert_white_24dp.xml │ │ │ ├── values-night │ │ │ │ └── colors.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── values │ │ │ │ ├── attrs.xml │ │ │ │ ├── string_array.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── styles.xml │ │ │ │ └── strings.xml │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-anydpi │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── layout │ │ │ │ ├── template_license_separator.xml │ │ │ │ ├── settings_activity.xml │ │ │ │ ├── template_license_apache_hint.xml │ │ │ │ ├── content_main.xml │ │ │ │ ├── dialog_imprint.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── dialog_input_notification_cron.xml │ │ │ │ ├── dialog_help.xml │ │ │ │ ├── notification_cron_item.xml │ │ │ │ └── activity_licenses.xml │ │ │ ├── menu │ │ │ │ └── menu_main.xml │ │ │ ├── xml │ │ │ │ └── root_preferences.xml │ │ │ ├── values-zh-rCN │ │ │ │ └── strings.xml │ │ │ ├── values-nl │ │ │ │ └── strings.xml │ │ │ ├── values-pt-rBR │ │ │ │ └── strings.xml │ │ │ └── values-de │ │ │ │ └── strings.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── github │ │ │ │ └── fi3te │ │ │ │ └── notificationcron │ │ │ │ ├── data │ │ │ │ ├── model │ │ │ │ │ ├── backup │ │ │ │ │ │ ├── Backup.kt │ │ │ │ │ │ ├── package-info.java │ │ │ │ │ │ ├── v00500 │ │ │ │ │ │ │ ├── Settings.kt │ │ │ │ │ │ │ └── NotificationCron.kt │ │ │ │ │ │ └── BackupV00500.kt │ │ │ │ │ ├── db │ │ │ │ │ │ ├── Database.kt │ │ │ │ │ │ ├── Settings.kt │ │ │ │ │ │ └── NotificationCron.kt │ │ │ │ │ └── NotificationCronInput.kt │ │ │ │ ├── remote │ │ │ │ │ ├── LocalDateTimeAdapter.kt │ │ │ │ │ ├── BackupJsonService.kt │ │ │ │ │ ├── DatabaseMappingUtil.kt │ │ │ │ │ ├── BackupMappingUtil.kt │ │ │ │ │ ├── FileUtil.kt │ │ │ │ │ └── StorageAccessFrameworkUtil.kt │ │ │ │ ├── DateTimeService.kt │ │ │ │ ├── receiver │ │ │ │ │ ├── BootCompletedReceiver.kt │ │ │ │ │ └── AlarmReceiver.kt │ │ │ │ ├── local │ │ │ │ │ ├── TimeConverter.kt │ │ │ │ │ ├── NotificationCronDao.kt │ │ │ │ │ ├── SettingsDao.kt │ │ │ │ │ └── AppDatabase.kt │ │ │ │ ├── CronService.kt │ │ │ │ └── AlarmService.kt │ │ │ │ └── ui │ │ │ │ ├── HelpDialog.kt │ │ │ │ ├── ImprintDialog.kt │ │ │ │ ├── ThemeUtil.kt │ │ │ │ ├── NotificationCronDragCallback.kt │ │ │ │ ├── settings │ │ │ │ ├── DurationPreference.kt │ │ │ │ └── SettingsActivity.kt │ │ │ │ ├── licenses │ │ │ │ └── LicensesActivity.kt │ │ │ │ ├── NotificationCronViewModel.kt │ │ │ │ ├── BackupViewModel.kt │ │ │ │ ├── NotificationCronDialog.kt │ │ │ │ ├── NotificationService.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── NotificationCronAdapter.kt │ │ └── AndroidManifest.xml │ └── androidTest │ │ └── java │ │ └── com │ │ └── github │ │ └── fi3te │ │ └── notificationcron │ │ └── data │ │ └── DatabaseMigrationTest.kt ├── proguard-rules.pro ├── schemas │ └── com.github.fi3te.notificationcron.data.local.AppDatabase │ │ ├── 1.json │ │ ├── 2.json │ │ ├── 3.json │ │ ├── 4.json │ │ └── 5.json └── build.gradle ├── settings.gradle ├── fastlane └── metadata │ └── android │ ├── de-DE │ ├── changelogs │ │ ├── 1.txt │ │ ├── 2.txt │ │ ├── 26010500.txt │ │ ├── 3.txt │ │ ├── 26010402.txt │ │ ├── 26010102.txt │ │ ├── 26010200.txt │ │ ├── 26010600.txt │ │ ├── 26010400.txt │ │ ├── 26010501.txt │ │ ├── 26010401.txt │ │ ├── 26010100.txt │ │ ├── 26010300.txt │ │ └── 26010101.txt │ ├── short_description.txt │ ├── images │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1.png │ │ │ └── 2.png │ └── full_description.txt │ └── en-US │ ├── changelogs │ ├── 1.txt │ ├── 2.txt │ ├── 26010500.txt │ ├── 3.txt │ ├── 26010402.txt │ ├── 26010102.txt │ ├── 26010200.txt │ ├── 26010600.txt │ ├── 26010400.txt │ ├── 26010401.txt │ ├── 26010501.txt │ ├── 26010100.txt │ ├── 26010300.txt │ └── 26010101.txt │ ├── short_description.txt │ ├── images │ ├── icon.png │ └── phoneScreenshots │ │ ├── 1.png │ │ └── 2.png │ └── full_description.txt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── README.md ├── .github └── workflows │ └── upload-apk.yml ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/1.txt: -------------------------------------------------------------------------------- 1 | * Erste Version 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1.txt: -------------------------------------------------------------------------------- 1 | * Initial version 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2.txt: -------------------------------------------------------------------------------- 1 | * Updated translations -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010500.txt: -------------------------------------------------------------------------------- 1 | * Added dark theme -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/3.txt: -------------------------------------------------------------------------------- 1 | * Revised error handling -------------------------------------------------------------------------------- /app/src/test/resources/backup_unknown_version.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "-" 3 | } -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/2.txt: -------------------------------------------------------------------------------- 1 | * Übersetzungen aktualisiert -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010402.txt: -------------------------------------------------------------------------------- 1 | * Updated URI handling -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010500.txt: -------------------------------------------------------------------------------- 1 | * Dunkles Design hinzugefügt -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/3.txt: -------------------------------------------------------------------------------- 1 | * Fehlerbehandlung überarbeitet -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010102.txt: -------------------------------------------------------------------------------- 1 | * Added Dutch translation -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010402.txt: -------------------------------------------------------------------------------- 1 | * URI-Behandlung aktualisiert -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010200.txt: -------------------------------------------------------------------------------- 1 | * Added possibility to arrange entries -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010102.txt: -------------------------------------------------------------------------------- 1 | * Niederländische Übersetzung hinzugefügt -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010600.txt: -------------------------------------------------------------------------------- 1 | * Added backup functionality 2 | * Fixed bugs -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010200.txt: -------------------------------------------------------------------------------- 1 | * Möglichkeit zur Anordnung von Einträgen hinzugefügt -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010400.txt: -------------------------------------------------------------------------------- 1 | * Display duration of the notifications can be set -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Scheduling recurring notifications on your phone 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010600.txt: -------------------------------------------------------------------------------- 1 | * Backup-Funktionalität hinzugefügt 2 | * Fehler behoben -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010400.txt: -------------------------------------------------------------------------------- 1 | * Anzeigedauer der Benachrichtigungen kann festgelegt werden -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/short_description.txt: -------------------------------------------------------------------------------- 1 | Wiederkehrende Benachrichtigungen auf dem Handy erhalten 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010401.txt: -------------------------------------------------------------------------------- 1 | * Added Portuguese translation 2 | * Added Chinese translation -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010501.txt: -------------------------------------------------------------------------------- 1 | * Updated translations 2 | * Improved display for large font size -------------------------------------------------------------------------------- /app/src/main/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/assets/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010100.txt: -------------------------------------------------------------------------------- 1 | * Added possibility to deactivate notifications 2 | * Added help dialog -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010501.txt: -------------------------------------------------------------------------------- 1 | * Übersetzungen angepasst 2 | * Darstellung für große Schriftgröße verbessert -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010401.txt: -------------------------------------------------------------------------------- 1 | * Portugiesische Übersetzung hinzugefügt 2 | * Chinesische Übersetzung hinzugefügt -------------------------------------------------------------------------------- /app/src/main/assets/images/app_icon_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/assets/images/app_icon_base.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/drawable/notification_icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010100.txt: -------------------------------------------------------------------------------- 1 | * Möglichkeit zur Deaktivierung von Benachrichtigungen hinzugefügt 2 | * Hilfe-Dialog hinzugefügt -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/de-DE/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /app/src/main/assets/images/app_icon_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/assets/images/app_icon_background.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010300.txt: -------------------------------------------------------------------------------- 1 | * Time in notification title can be hidden 2 | * When clicking on the notification an URI can be opened -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010300.txt: -------------------------------------------------------------------------------- 1 | * Uhrzeit im Benachrichtigungstitel kann ausgeblendet werden 2 | * Bei Klick auf Benachrichtigung kann URI geöffnet werden -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | Notification Cron is a straightforward tool to schedule recurring notifications on your phone without adding calendar entries. -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fi3te/NotificationCron/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/backup/Backup.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.backup 2 | 3 | sealed class Backup(val version: String) -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26010101.txt: -------------------------------------------------------------------------------- 1 | * Added support for multiline notifications 2 | * Improved display of notifications without text 3 | * Corrected grouping of notifications -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/full_description.txt: -------------------------------------------------------------------------------- 1 | Notification Cron ist ein einfaches Tool, um wiederkehrende Benachrichtigungen auf dem Handy zu erhalten, ohne Kalendereinträge zu erstellen. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de-DE/changelogs/26010101.txt: -------------------------------------------------------------------------------- 1 | * Unterstützung für mehrzeilige Benachrichtigungen hinzugefügt 2 | * Darstellung von Benachrichtigungen ohne Text verbessert 3 | * Gruppierung von Benachrichtigungen korrigiert -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/db/Database.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.db 2 | 3 | data class Database( 4 | val notificationCrons: List, 5 | val settings: Settings 6 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/db/Settings.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.db 2 | 3 | data class Settings ( 4 | val theme: Int, 5 | val notificationCancellation: Boolean, 6 | val displayDurationInSeconds: Int 7 | ) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Dec 19 09:33:22 CET 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/test/resources/backup_minified.json: -------------------------------------------------------------------------------- 1 | {"version":"500","notificationCrons":[{"cron":"0 0 7-22 * * ?","notificationTitle":"title","notificationText":"text","timeDisplay":true,"onClickUri":"","nextNotification":"2022-01-01T00:00","enabled":true}],"settings":{"theme":1,"notificationCancellation":true,"displayDurationInSeconds":5}} -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/backup/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Naming convention for backup versioning: 3 | * 4 | */ 5 | package com.github.fi3te.notificationcron.data.model.backup; -------------------------------------------------------------------------------- /app/src/main/res/layout/template_license_separator.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/settings_activity.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/backup/v00500/Settings.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.backup.v00500 2 | 3 | import com.squareup.moshi.JsonClass 4 | 5 | @JsonClass(generateAdapter = true) 6 | data class Settings( 7 | val theme: Int, 8 | val notificationCancellation: Boolean, 9 | val displayDurationInSeconds: Int 10 | ) -------------------------------------------------------------------------------- /app/src/main/res/layout/template_license_apache_hint.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/test/resources/backup_incomplete_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "500", 3 | "notificationCrons": [ 4 | { 5 | "cron": "0 0 7-22 * * ?", 6 | "notificationTitle": "title", 7 | "timeDisplay": true, 8 | "onClickUri": "", 9 | "nextNotification": "2022-01-01T00:00", 10 | "enabled": true 11 | } 12 | ], 13 | "settings": { 14 | "theme": 1, 15 | "displayDurationInSeconds": 5 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/test/java/com/github/fi3te/notificationcron/ui/NotificationServiceTest.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui 2 | 3 | import com.google.common.truth.Truth.assertThat 4 | import org.junit.Test 5 | 6 | class NotificationServiceTest { 7 | 8 | @Test 9 | fun testNewNotificationId() { 10 | for (e in 1..3) { 11 | for (i in 1..21) { 12 | assertThat("${newNotificationId()}").startsWith("$i") 13 | } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/test/resources/backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "500", 3 | "notificationCrons": [ 4 | { 5 | "cron": "0 0 7-22 * * ?", 6 | "notificationTitle": "title", 7 | "notificationText": "text", 8 | "timeDisplay": true, 9 | "onClickUri": "", 10 | "nextNotification": "2022-01-01T00:00", 11 | "enabled": true 12 | } 13 | ], 14 | "settings": { 15 | "theme": 1, 16 | "notificationCancellation": true, 17 | "displayDurationInSeconds": 5 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/ui/HelpDialog.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui 2 | 3 | import android.content.Context 4 | import com.afollestad.materialdialogs.MaterialDialog 5 | import com.afollestad.materialdialogs.customview.customView 6 | import com.github.fi3te.notificationcron.R 7 | 8 | fun showHelpDialog(windowContext: Context) { 9 | MaterialDialog(windowContext).show { 10 | title(R.string.help) 11 | customView(R.layout.dialog_help) 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/ui/ImprintDialog.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui 2 | 3 | import android.content.Context 4 | import com.afollestad.materialdialogs.MaterialDialog 5 | import com.afollestad.materialdialogs.customview.customView 6 | import com.github.fi3te.notificationcron.R 7 | 8 | fun showImprintDialog(windowContext: Context) { 9 | MaterialDialog(windowContext).show { 10 | title(R.string.imprint) 11 | customView(R.layout.dialog_imprint) 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_more_vert_grey_600_24dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/string_array.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @string/theme_follow_system 5 | @string/theme_auto_battery 6 | @string/theme_dark 7 | @string/theme_light 8 | 9 | 10 | -1 11 | 3 12 | 2 13 | 1 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/remote/LocalDateTimeAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.remote 2 | 3 | import com.squareup.moshi.FromJson 4 | import com.squareup.moshi.ToJson 5 | import java.time.LocalDateTime 6 | 7 | class LocalDateTimeAdapter { 8 | @ToJson fun toJson(localDateTime: LocalDateTime?): String? { 9 | return localDateTime?.toString() 10 | } 11 | 12 | @FromJson fun fromJson(json: String?): LocalDateTime? { 13 | return json?.let { LocalDateTime.parse(json) } 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/backup/BackupV00500.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.backup 2 | 3 | import com.github.fi3te.notificationcron.data.model.backup.v00500.NotificationCron 4 | import com.github.fi3te.notificationcron.data.model.backup.v00500.Settings 5 | import com.squareup.moshi.JsonClass 6 | 7 | const val V00500 = "500" 8 | 9 | @JsonClass(generateAdapter = true) 10 | data class BackupV00500( 11 | val notificationCrons: List, 12 | val settings: Settings 13 | ) : Backup(V00500) -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/ui/ThemeUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import androidx.appcompat.app.AppCompatDelegate 6 | import com.github.fi3te.notificationcron.data.local.SettingsDao 7 | 8 | fun reloadTheme(activity: Activity) { 9 | loadTheme(activity) 10 | activity.recreate() 11 | } 12 | 13 | fun loadTheme(context: Context) { 14 | val settings = SettingsDao(context).readSettings() 15 | AppCompatDelegate.setDefaultNightMode(settings.theme) 16 | } -------------------------------------------------------------------------------- /app/src/test/java/com/github/fi3te/notificationcron/data/DateTimeServiceTest.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data 2 | 3 | import com.google.common.truth.Truth.assertThat 4 | import org.junit.Test 5 | import java.time.LocalDateTime 6 | 7 | class DateTimeServiceTest { 8 | 9 | @Test 10 | fun testGetDayAndTimeStringAsInt() { 11 | assertThat(getDayAndTimeString(LocalDateTime.parse("2019-07-01T21:34:15"))).isEqualTo("01213415") 12 | assertThat(getDayAndTimeString(LocalDateTime.parse("2019-07-31T21:34:15"))).isEqualTo("31213415") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/backup/v00500/NotificationCron.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.backup.v00500 2 | 3 | import com.squareup.moshi.JsonClass 4 | import java.time.LocalDateTime 5 | 6 | @JsonClass(generateAdapter = true) 7 | data class NotificationCron( 8 | val cron: String, 9 | val notificationTitle: String, 10 | val notificationText: String, 11 | val timeDisplay: Boolean, 12 | val onClickUri: String, 13 | val nextNotification: LocalDateTime?, 14 | val enabled: Boolean, 15 | val position: Long? 16 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NotificationCron 2 | 3 | Notification Cron is a straightforward tool to schedule recurring notifications on your phone without adding calendar entries. 4 | 5 | [Get it on F-Droid](https://f-droid.org/packages/com.github.fi3te.notificationcron/) 8 | 9 |
10 | 11 | 12 |
13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_alert_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @color/bluish_green 4 | @color/bluish_green_dark 5 | @color/blue 6 | @android:color/background_light 7 | 8 | 9 | #009E73 10 | 11 | #006e47 12 | #0072B2 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/DateTimeService.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("SpellCheckingInspection") 2 | 3 | package com.github.fi3te.notificationcron.data 4 | 5 | import java.time.LocalDateTime 6 | import java.time.format.DateTimeFormatter 7 | 8 | val DATE_TIME_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss") 9 | val TIME_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss") 10 | 11 | fun getDayAndTimeString(): String { 12 | return getDayAndTimeString(LocalDateTime.now()) 13 | } 14 | 15 | fun getDayAndTimeString(localDateTime: LocalDateTime): String { 16 | return localDateTime.format(DateTimeFormatter.ofPattern("ddHHmmss")) 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/NotificationCronInput.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model 2 | 3 | import com.github.fi3te.notificationcron.data.model.db.NotificationCron 4 | 5 | data class NotificationCronInput( 6 | val cron: String, 7 | val notificationTitle: String, 8 | val notificationText: String, 9 | val timeDisplay: Boolean, 10 | val onClickUri: String 11 | ) 12 | 13 | fun NotificationCronInput.toNotificationCron() = NotificationCron( 14 | cron = cron, 15 | notificationTitle = notificationTitle, 16 | notificationText = notificationText, 17 | timeDisplay = timeDisplay, 18 | onClickUri = onClickUri 19 | ) 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/receiver/BootCompletedReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.receiver 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.BroadcastReceiver 5 | import android.content.Context 6 | import android.content.Intent 7 | import com.github.fi3te.notificationcron.data.scheduleAlarms 8 | 9 | class BootCompletedReceiver : BroadcastReceiver() { 10 | 11 | @SuppressLint("UnsafeProtectedBroadcastReceiver") 12 | override fun onReceive(context: Context?, intent: Intent?) { 13 | if (context != null) { 14 | Thread { 15 | scheduleAlarms(context) 16 | }.start() 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/local/TimeConverter.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.local 2 | 3 | import androidx.room.TypeConverter 4 | import java.time.Instant 5 | import java.time.LocalDateTime 6 | import java.time.ZoneOffset 7 | 8 | class TimeConverter { 9 | 10 | @TypeConverter 11 | fun timestampToLocalDateTime(value: Long?): LocalDateTime? { 12 | return value?.let { 13 | LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC) 14 | } 15 | } 16 | 17 | @TypeConverter 18 | fun localDateTimeToTimestamp(date: LocalDateTime?): Long? { 19 | return date?.atZone(ZoneOffset.UTC)?.toInstant()?.toEpochMilli() 20 | } 21 | } -------------------------------------------------------------------------------- /.github/workflows/upload-apk.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: [created] 4 | 5 | jobs: 6 | upload_apk: 7 | name: Upload APK for release 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v2 12 | 13 | - name: Set up Java environment 14 | uses: actions/setup-java@v1 15 | with: 16 | java-version: '11' 17 | 18 | - name: Make gradlew executable 19 | run: chmod +x ./gradlew 20 | 21 | - name: Build a debug APK 22 | run: ./gradlew clean assembleDebug 23 | 24 | - name: Upload the APK 25 | uses: skx/github-action-publish-binaries@master 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | with: 29 | args: 'app/build/outputs/apk/debug/app-debug.apk' -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/model/db/NotificationCron.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.model.db 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import java.time.LocalDateTime 7 | 8 | @Entity(tableName = "notification_cron") 9 | data class NotificationCron( 10 | @PrimaryKey(autoGenerate = true) val id: Long = 0, 11 | @ColumnInfo(name = "cron") val cron: String, 12 | @ColumnInfo(name = "notification_title") val notificationTitle: String = "", 13 | @ColumnInfo(name = "notification_text") val notificationText: String = "", 14 | @ColumnInfo(name = "time_display") val timeDisplay: Boolean = true, 15 | @ColumnInfo(name = "on_click_uri") val onClickUri: String = "", 16 | @ColumnInfo(name = "next_notification") var nextNotification: LocalDateTime? = null, 17 | @ColumnInfo(name = "enabled") var enabled: Boolean = true, 18 | @ColumnInfo(name = "position") var position: Long? = null 19 | ) -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | 15 | 16 | 20 | 21 | 25 | 26 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_imprint.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 14 | 15 | 16 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | 16dp 4 | 8dp 5 | 16sp 6 | 88dp 7 | 20dp 8 | 10dp 9 | 20dp 10 | 10dp 11 | 12 | 88dp 13 | 12dp 14 | 2dp 15 | 12dp 16 | 16dp 17 | 8dp 18 | 32dp 19 | 16dp 20 | 16dp 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/ui/NotificationCronDragCallback.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui 2 | 3 | import androidx.recyclerview.widget.ItemTouchHelper 4 | import androidx.recyclerview.widget.RecyclerView 5 | 6 | class NotificationCronDragCallback(private val adapter: NotificationCronAdapter) : 7 | ItemTouchHelper.SimpleCallback( 8 | ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0 9 | ) { 10 | 11 | override fun onMove( 12 | recyclerView: RecyclerView, 13 | viewHolder: RecyclerView.ViewHolder, 14 | target: RecyclerView.ViewHolder 15 | ): Boolean { 16 | val fromPosition = viewHolder.adapterPosition 17 | val toPosition = target.adapterPosition 18 | adapter.onCronMove(fromPosition, toPosition) 19 | return true 20 | } 21 | 22 | override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { 23 | adapter.onCronClear() 24 | super.clearView(recyclerView, viewHolder) 25 | } 26 | 27 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {} 28 | 29 | interface DragListener { 30 | fun onCronMove(fromPosition: Int, toPosition: Int) 31 | fun onCronClear() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | kapt.incremental.apt=true 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/remote/BackupJsonService.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.remote 2 | 3 | import com.github.fi3te.notificationcron.data.model.backup.Backup 4 | import com.github.fi3te.notificationcron.data.model.backup.BackupV00500 5 | import com.github.fi3te.notificationcron.data.model.backup.V00500 6 | import com.squareup.moshi.JsonAdapter 7 | import com.squareup.moshi.JsonDataException 8 | import com.squareup.moshi.Moshi 9 | import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory 10 | 11 | 12 | class BackupJsonService { 13 | 14 | private val jsonAdapter: JsonAdapter 15 | 16 | init { 17 | val moshi = Moshi.Builder() 18 | .add(LocalDateTimeAdapter()) 19 | .add( 20 | PolymorphicJsonAdapterFactory.of(Backup::class.java, "version") 21 | .withSubtype(BackupV00500::class.java, V00500) 22 | ) 23 | .build() 24 | 25 | jsonAdapter = moshi.adapter(Backup::class.java) 26 | } 27 | 28 | @Throws(JsonDataException::class) 29 | fun readJson(json: String): Backup? { 30 | return jsonAdapter.fromJson(json) 31 | } 32 | 33 | fun writeJson(obj: Backup): String { 34 | return jsonAdapter.toJson(obj) 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/remote/DatabaseMappingUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.remote 2 | 3 | import com.github.fi3te.notificationcron.data.model.backup.Backup 4 | import com.github.fi3te.notificationcron.data.model.backup.BackupV00500 5 | import com.github.fi3te.notificationcron.data.model.db.Database 6 | import com.github.fi3te.notificationcron.data.model.db.NotificationCron 7 | import com.github.fi3te.notificationcron.data.model.db.Settings 8 | import com.github.fi3te.notificationcron.data.model.backup.v00500.NotificationCron as NotificationCronV00500 9 | import com.github.fi3te.notificationcron.data.model.backup.v00500.Settings as SettingsV00500 10 | 11 | fun map(database: Database): Backup = database.run { 12 | return BackupV00500( 13 | notificationCrons.map { map(it) }, 14 | map(settings) 15 | ) 16 | } 17 | 18 | private fun map(notificationCron: NotificationCron): NotificationCronV00500 = notificationCron.run { 19 | return NotificationCronV00500( 20 | cron, 21 | notificationTitle, 22 | notificationText, 23 | timeDisplay, 24 | onClickUri, 25 | nextNotification, 26 | enabled, 27 | position 28 | ) 29 | } 30 | 31 | private fun map(settings: Settings): SettingsV00500 = settings.run { 32 | return SettingsV00500( 33 | theme, notificationCancellation, displayDurationInSeconds 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 17 | 23 | 24 | 27 | 28 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/local/NotificationCronDao.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.local 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.* 5 | import com.github.fi3te.notificationcron.data.model.db.NotificationCron 6 | 7 | @Dao 8 | interface NotificationCronDao { 9 | 10 | @Query("SELECT * FROM notification_cron") 11 | fun findAll(): List 12 | 13 | @Query("SELECT * FROM notification_cron ORDER BY position") 14 | fun findAllOrderedAndLive(): LiveData> 15 | 16 | @Query("SELECT * FROM notification_cron WHERE id=:notificationCronId") 17 | fun findById(notificationCronId: Long): NotificationCron? 18 | 19 | @Query("SELECT IFNULL(MAX(position) + 1, 0) FROM notification_cron") 20 | fun getNextPosition(): Long 21 | 22 | @Query("SELECT * FROM notification_cron WHERE position=:notificationCronPosition") 23 | fun findByPosition(notificationCronPosition: Long): NotificationCron 24 | 25 | @Insert 26 | fun insert(notificationCron: NotificationCron): Long 27 | 28 | @Insert 29 | fun insertAll(notificationCrons: List) 30 | 31 | @Update 32 | fun update(notificationCron: NotificationCron) 33 | 34 | @Update(onConflict = OnConflictStrategy.REPLACE) 35 | fun update(notificationCrons: List) 36 | 37 | @Delete 38 | fun delete(notificationCron: NotificationCron) 39 | 40 | @Query("DELETE FROM notification_cron") 41 | fun deleteAll() 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/data/remote/BackupMappingUtil.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.data.remote 2 | 3 | import com.github.fi3te.notificationcron.data.model.backup.Backup 4 | import com.github.fi3te.notificationcron.data.model.backup.BackupV00500 5 | import com.github.fi3te.notificationcron.data.model.backup.v00500.Settings as SettingsV00500 6 | import com.github.fi3te.notificationcron.data.model.backup.v00500.NotificationCron as NotificationCronV00500 7 | import com.github.fi3te.notificationcron.data.model.db.Database 8 | import com.github.fi3te.notificationcron.data.model.db.NotificationCron 9 | import com.github.fi3te.notificationcron.data.model.db.Settings 10 | 11 | fun map(backup: Backup): Database { 12 | return when (backup) { 13 | is BackupV00500 -> map(backup) 14 | } 15 | } 16 | 17 | private fun map(backup: BackupV00500): Database = backup.run { 18 | return Database( 19 | notificationCrons.map { map(it) }, 20 | map(settings) 21 | ) 22 | } 23 | 24 | private fun map(notificationCron: NotificationCronV00500): NotificationCron = notificationCron.run { 25 | return NotificationCron( 26 | 0, 27 | cron, 28 | notificationTitle, 29 | notificationText, 30 | timeDisplay, 31 | onClickUri, 32 | nextNotification, 33 | enabled, 34 | position 35 | ) 36 | } 37 | 38 | private fun map(settings: SettingsV00500): Settings = settings.run { 39 | return Settings( 40 | theme, notificationCancellation, displayDurationInSeconds 41 | ) 42 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/fi3te/notificationcron/ui/settings/DurationPreference.kt: -------------------------------------------------------------------------------- 1 | package com.github.fi3te.notificationcron.ui.settings 2 | 3 | import android.content.Context 4 | import android.text.InputType 5 | import android.util.AttributeSet 6 | import android.widget.Button 7 | import androidx.core.widget.doAfterTextChanged 8 | import androidx.preference.EditTextPreference 9 | import com.github.fi3te.notificationcron.R 10 | import java.util.regex.Pattern 11 | 12 | class DurationPreference : EditTextPreference { 13 | 14 | constructor(context: Context?) : super(context) 15 | 16 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) 17 | 18 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( 19 | context, 20 | attrs, 21 | defStyleAttr 22 | ) 23 | 24 | constructor( 25 | context: Context?, 26 | attrs: AttributeSet?, 27 | defStyleAttr: Int, 28 | defStyleRes: Int 29 | ) : super(context, attrs, defStyleAttr, defStyleRes) 30 | 31 | init { 32 | initEditText() 33 | } 34 | 35 | private fun initEditText() = setOnBindEditTextListener { editText -> 36 | editText.inputType = InputType.TYPE_CLASS_NUMBER 37 | editText.doAfterTextChanged { editable -> 38 | requireNotNull(editable) 39 | val isPositiveInteger = Pattern.matches("^[1-9]+[0-9]*$", editable.toString()) 40 | editText.error = 41 | if (isPositiveInteger) null else editText.context.getString(R.string.invalid_duration) 42 | editText.rootView.findViewById