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