Add TasksContentProvider

pull/1025/head
Alex Baker 6 years ago
parent 609a8f8f23
commit e6dfbea4cb

@ -161,6 +161,16 @@
android:name=".activities.CameraActivity"
android:theme="@style/TranslucentDialog"/>
<activity android:name=".activities.UriHandler">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:scheme="content"
android:host="${applicationId}" />
</intent-filter>
</activity>
<activity android:name="com.todoroo.astrid.activity.TaskEditActivity">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW"/>
@ -255,6 +265,12 @@
android:name="com.todoroo.astrid.provider.Astrid2TaskProvider"
android:readPermission="${applicationId}.permission.READ_TASKS"/>
<provider
android:authorities="${applicationId}"
android:exported="true"
android:name="org.tasks.provider.TasksContentProvider"
android:readPermission="${applicationId}.permission.READ_TASKS"/>
<provider
android:authorities="${applicationId}.file_provider"
android:exported="false"

@ -19,7 +19,7 @@ import timber.log.Timber
import java.util.*
@Entity(
tableName = "tasks",
tableName = Task.TABLE_NAME,
indices = [
Index(name = "t_rid", value = ["remoteId"], unique = true),
Index(name = "active_and_visible", value = ["completed", "deleted", "hideUntil"])])
@ -491,10 +491,11 @@ class Task : Parcelable {
}
companion object {
const val TABLE_NAME = "tasks"
// --- table and uri
/** table for this model */
@JvmField val TABLE = Table("tasks")
@JvmField val FIELDS = Field.field("tasks.*")
@JvmField val TABLE = Table(TABLE_NAME)
@JvmField val FIELDS = Field.field("$TABLE_NAME.*")
const val NO_ID: Long = 0
// --- properties

@ -150,7 +150,7 @@ class Astrid2TaskProvider : ContentProvider() {
private val tasks: Cursor
get() {
val hilt = hilt()
hilt.firebase.logEvent(R.string.event_query_legacy_content_provider)
hilt.firebase.logEvent(R.string.event_astrid2taskprovider)
val tasks = hilt.contentProviderDao.getAstrid2TaskProviderTasks()
val ret = MatrixCursor(TASK_FIELD_LIST)
for (task in tasks) {

@ -0,0 +1,54 @@
package org.tasks.activities
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.todoroo.astrid.dao.TaskDao
import dagger.hilt.android.AndroidEntryPoint
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.tasks.intents.TaskIntents
import org.tasks.provider.TasksContentProvider
import org.tasks.provider.TasksContentProvider.Companion.URI_OPEN_TASK
import timber.log.Timber
import java.util.*
import javax.inject.Inject
@AndroidEntryPoint
class UriHandler : AppCompatActivity() {
@Inject lateinit var taskDao: TaskDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
when (TasksContentProvider.URI_MATCHER.match(intent.data ?: Uri.EMPTY)) {
URI_OPEN_TASK -> {
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()
}
}
}
}

@ -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<TagData>
@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
}

@ -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<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
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<out String>?) = 0
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): 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)
}
}
}

@ -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);
}

@ -377,5 +377,6 @@
<string name="param_user_pro">user_pro</string>
<string name="param_click">click</string>
<string name="event_xml_import">xml_import</string>
<string name="event_query_legacy_content_provider">query_astrid2taskprovider</string>
<string name="event_todoagenda">cp_todoagenda</string>
<string name="event_astrid2taskprovider">cp_astrid2taskprovider</string>
</resources>

Loading…
Cancel
Save