diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a1d4152a6..1eeffb6fa 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -161,6 +161,16 @@
android:name=".activities.CameraActivity"
android:theme="@style/TranslucentDialog"/>
+
+
+
+
+
+
+
+
@@ -255,6 +265,12 @@
android:name="com.todoroo.astrid.provider.Astrid2TaskProvider"
android:readPermission="${applicationId}.permission.READ_TASKS"/>
+
+
{
+ val id = intent.data?.lastPathSegment?.toLongOrNull() ?: 0
+ if (id > 0) {
+ Single.fromCallable { Optional.ofNullable(taskDao.fetch(id))}
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doAfterTerminate(this::finish)
+ .subscribe(
+ { startActivity(TaskIntents.getEditTaskIntent(this, it.get())) },
+ Timber::e)
+ } else {
+ startActivity(TaskIntents.getNewTaskIntent(this, null))
+ }
+ val intent = if (id > 0) {
+ val task = taskDao.fetch(id)
+ TaskIntents.getEditTaskIntent(this, task)
+ } else {
+ TaskIntents.getNewTaskIntent(this, null)
+ }
+ startActivity(intent)
+ }
+ else -> {
+ Timber.w("Invalid uri: ${intent.data}")
+ finish()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/data/ContentProviderDao.kt b/app/src/main/java/org/tasks/data/ContentProviderDao.kt
index 4ed298dab..f31aaad3b 100644
--- a/app/src/main/java/org/tasks/data/ContentProviderDao.kt
+++ b/app/src/main/java/org/tasks/data/ContentProviderDao.kt
@@ -1,7 +1,10 @@
package org.tasks.data
+import android.database.Cursor
import androidx.room.Dao
import androidx.room.Query
+import androidx.room.RawQuery
+import androidx.sqlite.db.SupportSQLiteQuery
import com.todoroo.astrid.data.Task
@Dao
@@ -26,4 +29,19 @@ interface ContentProviderDao {
@Query("SELECT * FROM tagdata WHERE name IS NOT NULL AND name != '' ORDER BY UPPER(name) ASC")
fun tagDataOrderedByName(): List
+
+ @Query("SELECT * FROM tasks")
+ fun getTasks(): Cursor
+
+ @Query("""
+ SELECT caldav_lists.*, caldav_accounts.cda_name
+ FROM caldav_lists
+ INNER JOIN caldav_accounts ON cdl_account = cda_uuid""")
+ fun getLists(): Cursor
+
+ @Query("SELECT * FROM google_task_lists")
+ fun getGoogleTaskLists(): Cursor
+
+ @RawQuery
+ fun rawQuery(query: SupportSQLiteQuery): Cursor
}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/provider/TasksContentProvider.kt b/app/src/main/java/org/tasks/provider/TasksContentProvider.kt
new file mode 100644
index 000000000..65d6d1adb
--- /dev/null
+++ b/app/src/main/java/org/tasks/provider/TasksContentProvider.kt
@@ -0,0 +1,92 @@
+package org.tasks.provider
+
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.content.UriMatcher
+import android.database.Cursor
+import android.net.Uri
+import androidx.sqlite.db.SupportSQLiteQueryBuilder
+import com.todoroo.astrid.data.Task
+import dagger.hilt.EntryPoint
+import dagger.hilt.InstallIn
+import dagger.hilt.android.EntryPointAccessors
+import dagger.hilt.android.components.ApplicationComponent
+import org.tasks.BuildConfig
+import org.tasks.R
+import org.tasks.analytics.Firebase
+import org.tasks.data.ContentProviderDao
+
+class TasksContentProvider : ContentProvider() {
+
+ @EntryPoint
+ @InstallIn(ApplicationComponent::class)
+ interface TasksContentProviderEntryPoint {
+ val contentProviderDao: ContentProviderDao
+ val firebase: Firebase
+ }
+
+ override fun insert(uri: Uri, values: ContentValues?): Uri? = null
+
+ override fun query(
+ uri: Uri,
+ projection: Array?,
+ selection: String?,
+ selectionArgs: Array?,
+ sortOrder: String?): Cursor? {
+ val hilt = hilt()
+ return when (URI_MATCHER.match(uri)) {
+ URI_TODO_AGENDA -> {
+ hilt.firebase.logEvent(R.string.event_todoagenda)
+ hilt.contentProviderDao.rawQuery(
+ SupportSQLiteQueryBuilder
+ .builder(TODO_AGENDA_TABLES)
+ .selection(selection, selectionArgs)
+ .create())
+ }
+ URI_TASKS -> hilt.contentProviderDao.getTasks()
+ URI_LISTS -> hilt.contentProviderDao.getLists()
+ URI_GOOGLE_TASK_LISTS -> hilt.contentProviderDao.getGoogleTaskLists()
+ else -> throw IllegalStateException("Unrecognized URI: $uri")
+ }
+ }
+
+ override fun onCreate() = true
+
+ override fun update(
+ uri: Uri,
+ values: ContentValues?,
+ selection: String?,
+ selectionArgs: Array?) = 0
+
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = 0
+
+ override fun getType(uri: Uri): String? = null
+
+ private fun hilt() =
+ EntryPointAccessors.fromApplication(
+ context!!.applicationContext,
+ TasksContentProviderEntryPoint::class.java)
+
+ companion object {
+ private const val TODO_AGENDA_TABLES =
+ """${Task.TABLE_NAME}
+ LEFT JOIN google_tasks ON gt_task = _id
+ LEFT JOIN google_task_lists ON gtl_remote_id = gt_list_id
+ LEFT JOIN caldav_tasks ON cd_task = _id
+ LEFT JOIN caldav_lists ON cdl_uuid = cd_calendar"""
+ private const val AUTHORITY = BuildConfig.APPLICATION_ID;
+ @JvmField val CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY")
+ const val URI_TASKS = 1
+ const val URI_OPEN_TASK = 2
+ private const val URI_LISTS = 3
+ private const val URI_GOOGLE_TASK_LISTS = 4
+ private const val URI_TODO_AGENDA = 100
+ val URI_MATCHER = UriMatcher(UriMatcher.NO_MATCH).apply {
+ addURI(AUTHORITY, "tasks", URI_TASKS)
+ addURI(AUTHORITY, "tasks/*", URI_OPEN_TASK)
+ addURI(AUTHORITY, "lists", URI_LISTS)
+ addURI(AUTHORITY, "google_lists", URI_GOOGLE_TASK_LISTS)
+ addURI(AUTHORITY, "todoagenda", URI_TODO_AGENDA)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/receivers/RefreshReceiver.java b/app/src/main/java/org/tasks/receivers/RefreshReceiver.java
index d66c4e14a..b7ef1cfdd 100644
--- a/app/src/main/java/org/tasks/receivers/RefreshReceiver.java
+++ b/app/src/main/java/org/tasks/receivers/RefreshReceiver.java
@@ -1,5 +1,6 @@
package org.tasks.receivers;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
@@ -13,6 +14,7 @@ import org.tasks.R;
import org.tasks.injection.InjectingJobIntentService;
import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Preferences;
+import org.tasks.provider.TasksContentProvider;
import timber.log.Timber;
@AndroidEntryPoint
@@ -31,7 +33,9 @@ public class RefreshReceiver extends InjectingJobIntentService {
}
try {
- context.getContentResolver().notifyChange(Astrid2TaskProvider.CONTENT_URI, null);
+ ContentResolver cr = context.getContentResolver();
+ cr.notifyChange(TasksContentProvider.CONTENT_URI, null);
+ cr.notifyChange(Astrid2TaskProvider.CONTENT_URI, null);
} catch (Exception e) {
Timber.e(e);
}
diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml
index 8617a08c5..47c3948f0 100644
--- a/app/src/main/res/values/keys.xml
+++ b/app/src/main/res/values/keys.xml
@@ -377,5 +377,6 @@
user_pro
click
xml_import
- query_astrid2taskprovider
+ cp_todoagenda
+ cp_astrid2taskprovider