diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 00a9a0f36..f8c4de799 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -177,6 +177,11 @@
+
+
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
index 489e81dcf..d592a2a7d 100644
--- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt
@@ -31,6 +31,7 @@ import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.fragments.*
import com.simplemobiletools.calendar.pro.helpers.*
import com.simplemobiletools.calendar.pro.helpers.Formatter
+import com.simplemobiletools.calendar.pro.jobs.CalDAVUpdateListener
import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType
import com.simplemobiletools.calendar.pro.models.ListEvent
@@ -102,6 +103,10 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
}
checkAppOnSDCard()
+
+ if (savedInstanceState == null) {
+ checkCalDAVUpdateListener()
+ }
}
override fun onResume() {
@@ -265,6 +270,19 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
mSearchMenuItem?.collapseActionView()
}
+ private fun checkCalDAVUpdateListener() {
+ if (isNougatPlus()) {
+ val updateListener = CalDAVUpdateListener()
+ if (config.caldavSync) {
+ if (!updateListener.isScheduled(applicationContext)) {
+ updateListener.scheduleJob(applicationContext)
+ }
+ } else {
+ updateListener.cancelJob(applicationContext)
+ }
+ }
+ }
+
@SuppressLint("NewApi")
private fun checkShortcuts() {
val appIconColor = config.appIconColor
diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt
new file mode 100644
index 000000000..510ca3a13
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt
@@ -0,0 +1,65 @@
+package com.simplemobiletools.calendar.pro.jobs
+
+import android.annotation.TargetApi
+import android.app.job.JobInfo
+import android.app.job.JobParameters
+import android.app.job.JobScheduler
+import android.app.job.JobService
+import android.content.ComponentName
+import android.content.Context
+import android.os.Build
+import android.os.Handler
+import android.provider.CalendarContract
+import com.simplemobiletools.calendar.pro.extensions.recheckCalDAVCalendars
+
+// based on https://developer.android.com/reference/android/app/job/JobInfo.Builder.html#addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri)
+@TargetApi(Build.VERSION_CODES.N)
+class CalDAVUpdateListener : JobService() {
+ companion object {
+ const val CALDAV_EVENT_CONTENT_JOB = 1
+ }
+
+ private val mHandler = Handler()
+ private val mWorker = Runnable {
+ scheduleJob(this@CalDAVUpdateListener)
+ jobFinished(mRunningParams, false)
+ }
+
+ private var mRunningParams: JobParameters? = null
+
+ fun scheduleJob(context: Context) {
+ val componentName = ComponentName(context, CalDAVUpdateListener::class.java)
+ val uri = CalendarContract.Calendars.CONTENT_URI
+ JobInfo.Builder(CALDAV_EVENT_CONTENT_JOB, componentName).apply {
+ addTriggerContentUri(JobInfo.TriggerContentUri(uri, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS))
+ context.getSystemService(JobScheduler::class.java).schedule(build())
+ }
+ }
+
+ fun isScheduled(context: Context): Boolean {
+ val jobScheduler = context.getSystemService(JobScheduler::class.java)
+ val jobs = jobScheduler.allPendingJobs ?: return false
+ return jobs.any { it.id == CALDAV_EVENT_CONTENT_JOB }
+ }
+
+ fun cancelJob(context: Context) {
+ val js = context.getSystemService(JobScheduler::class.java)
+ js.cancel(CALDAV_EVENT_CONTENT_JOB)
+ }
+
+ override fun onStartJob(params: JobParameters): Boolean {
+ mRunningParams = params
+
+ if (params.triggeredContentAuthorities != null && params.triggeredContentUris != null) {
+ recheckCalDAVCalendars {}
+ }
+
+ mHandler.post(mWorker)
+ return true
+ }
+
+ override fun onStopJob(params: JobParameters): Boolean {
+ mHandler.removeCallbacks(mWorker)
+ return false
+ }
+}