Commit 07b59fb6 authored by Ricki Hirner's avatar Ricki Hirner

Update for OpenTasks support

* ical4android update
* use uid field for tasks
* require OpenTasks 1.1.8.2
parent 3e2e17bd
......@@ -9,10 +9,7 @@ package at.bitfire.davdroid
import android.accounts.Account
import android.accounts.AccountManager
import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.*
import android.os.Build
import android.os.Bundle
import android.os.Parcel
......@@ -31,10 +28,12 @@ import at.bitfire.davdroid.settings.ISettings
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.ical4android.TaskProvider
import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.GroupMethod
import okhttp3.HttpUrl
import org.apache.commons.lang3.StringUtils
import org.dmfs.tasks.contract.TaskContract
import java.util.*
import java.util.logging.Level
......@@ -46,7 +45,7 @@ class AccountSettings @Throws(InvalidAccountException::class) constructor(
companion object {
val CURRENT_VERSION = 7
val CURRENT_VERSION = 8
val KEY_SETTINGS_VERSION = "version"
val KEY_USERNAME = "user_name"
......@@ -210,6 +209,8 @@ class AccountSettings @Throws(InvalidAccountException::class) constructor(
try {
val updateProc = this::class.java.getDeclaredMethod("update_${fromVersion}_$toVersion")
updateProc.invoke(this)
Logger.log.info("Account version update successful")
accountManager.setUserData(account, KEY_SETTINGS_VERSION, toVersion.toString())
} catch (e: Exception) {
Logger.log.log(Level.SEVERE, "Couldn't update account settings", e)
......@@ -217,6 +218,32 @@ class AccountSettings @Throws(InvalidAccountException::class) constructor(
}
}
@Suppress("unused")
private fun update_7_8() {
TaskProvider.acquire(context, TaskProvider.ProviderName.OpenTasks)?.let { provider ->
// ETag is now in sync_version instead of sync1
// UID is now in _uid instead of sync2
val cursor = provider.client.query(TaskProvider.syncAdapterUri(provider.tasksUri(), account),
arrayOf(TaskContract.Tasks._ID, TaskContract.Tasks.SYNC1, TaskContract.Tasks.SYNC2),
"${TaskContract.Tasks.ACCOUNT_TYPE}=? AND ${TaskContract.Tasks.ACCOUNT_NAME}=?",
arrayOf(account.type, account.name), null)
while (cursor.moveToNext()) {
val id = cursor.getLong(0)
val eTag = cursor.getString(1)
val uid = cursor.getString(2)
val values = ContentValues(4)
values.put(TaskContract.Tasks._UID, uid)
values.put(TaskContract.Tasks.SYNC_VERSION, eTag)
values.putNull(TaskContract.Tasks.SYNC1)
values.putNull(TaskContract.Tasks.SYNC2)
Logger.log.log(Level.FINER, "Updating task $id", values)
provider.client.update(
TaskProvider.syncAdapterUri(ContentUris.withAppendedId(provider.tasksUri(), id), account),
values, null, null)
}
}
}
@Suppress("unused")
private fun update_6_7() {
// add calendar colors
......@@ -391,7 +418,7 @@ class AccountSettings @Throws(InvalidAccountException::class) constructor(
}
}
AndroidTaskList.acquireTaskProvider(context.contentResolver)?.use { provider ->
AndroidTaskList.acquireTaskProvider(context)?.use { provider ->
try {
val taskLists = AndroidTaskList.find(account, provider, LocalTaskList.Factory, null, null)
for (taskList in taskLists)
......
......@@ -25,7 +25,7 @@ import java.io.Closeable
import java.io.File
import java.net.InetSocketAddress
import java.net.Proxy
import java.text.SimpleDateFormat
import java.text.DateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.logging.Level
......@@ -156,7 +156,7 @@ class HttpClient private constructor(
private object UserAgentInterceptor: Interceptor {
private val userAgentDate = SimpleDateFormat("yyyy/MM/dd", Locale.US).format(Date(BuildConfig.buildTime))
private val userAgentDate = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US).format(Date(BuildConfig.buildTime))
private val userAgent = "DAVdroid/${BuildConfig.VERSION_NAME} ($userAgentDate; dav4android; okhttp3) Android/${Build.VERSION.RELEASE}"
override fun intercept(chain: Interceptor.Chain): Response {
......
......@@ -12,7 +12,7 @@ import android.content.ContentProviderOperation
import android.content.ContentValues
import android.provider.CalendarContract.Events
import at.bitfire.ical4android.*
import org.dmfs.provider.tasks.TaskContract.Tasks
import org.dmfs.tasks.contract.TaskContract.Tasks
import java.io.FileNotFoundException
import java.text.ParseException
import java.util.*
......@@ -20,8 +20,7 @@ import java.util.*
class LocalTask: AndroidTask, LocalResource {
companion object {
val COLUMN_ETAG = Tasks.SYNC1
val COLUMN_UID = Tasks.SYNC2
val COLUMN_ETAG = Tasks.SYNC_VERSION
val COLUMN_SEQUENCE = Tasks.SYNC3
}
......@@ -51,7 +50,6 @@ class LocalTask: AndroidTask, LocalResource {
eTag = values.getAsString(COLUMN_ETAG)
val task = requireNotNull(task)
task.uid = values.getAsString(COLUMN_UID)
task.sequence = values.getAsInteger(COLUMN_SEQUENCE)
}
......@@ -61,7 +59,6 @@ class LocalTask: AndroidTask, LocalResource {
val task = requireNotNull(task)
builder .withValue(Tasks._SYNC_ID, fileName)
.withValue(COLUMN_UID, task.uid)
.withValue(COLUMN_SEQUENCE, task.sequence)
.withValue(COLUMN_ETAG, eTag)
}
......@@ -77,7 +74,7 @@ class LocalTask: AndroidTask, LocalResource {
val values = ContentValues(2)
values.put(Tasks._SYNC_ID, newFileName)
values.put(COLUMN_UID, uid)
values.put(Tasks._UID, uid)
taskList.provider.client.update(taskSyncURI(), values, null, null)
fileName = newFileName
......
......@@ -21,8 +21,8 @@ import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.AndroidTaskListFactory
import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.ical4android.TaskProvider
import org.dmfs.provider.tasks.TaskContract.TaskLists
import org.dmfs.provider.tasks.TaskContract.Tasks
import org.dmfs.tasks.contract.TaskContract.TaskLists
import org.dmfs.tasks.contract.TaskContract.Tasks
import java.io.FileNotFoundException
class LocalTaskList private constructor(
......@@ -48,7 +48,7 @@ class LocalTaskList private constructor(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return context.packageManager.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
else {
val provider = TaskProvider.acquire(context.contentResolver, TaskProvider.ProviderName.OpenTasks)
val provider = TaskProvider.acquire(context, TaskProvider.ProviderName.OpenTasks)
provider?.use { return true }
return false
}
......
......@@ -8,10 +8,18 @@
package at.bitfire.davdroid.syncadapter
import android.accounts.Account
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.*
import android.content.pm.PackageManager
import android.database.DatabaseUtils
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.NotificationCompat
import at.bitfire.davdroid.AccountSettings
import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.model.CollectionInfo
import at.bitfire.davdroid.model.ServiceDB
......@@ -19,9 +27,10 @@ import at.bitfire.davdroid.model.ServiceDB.Collections
import at.bitfire.davdroid.model.ServiceDB.Services
import at.bitfire.davdroid.resource.LocalTaskList
import at.bitfire.davdroid.settings.ISettings
import at.bitfire.davdroid.ui.NotificationUtils
import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.TaskProvider
import org.dmfs.provider.tasks.TaskContract
import org.dmfs.tasks.contract.TaskContract
import java.util.logging.Level
/**
......@@ -38,7 +47,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
override fun sync(settings: ISettings, account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) {
try {
val taskProvider = TaskProvider.fromProviderClient(provider)
val taskProvider = TaskProvider.fromProviderClient(context, provider)
val accountSettings = AccountSettings(context, settings, account)
/* don't run sync if
- sync conditions (e.g. "sync only in WiFi") are not met AND
......@@ -55,8 +64,30 @@ class TasksSyncAdapterService: SyncAdapterService() {
it.performSync()
}
}
} catch (e: TaskProvider.ProviderTooOldException) {
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notify = NotificationCompat.Builder(context, NotificationUtils.CHANNEL_SYNC_PROBLEMS)
.setSmallIcon(R.drawable.ic_sync_error_notification)
.setContentTitle(context.getString(R.string.sync_error_opentasks_too_old))
.setContentText(context.getString(R.string.sync_error_opentasks_required_version, e.provider.minVersionName, e.installedVersionName))
.setCategory(NotificationCompat.CATEGORY_ERROR)
try {
val icon = context.packageManager.getApplicationIcon(e.provider.packageName)
if (icon is BitmapDrawable)
notify.setLargeIcon(icon.bitmap)
} catch(ignored: PackageManager.NameNotFoundException) {}
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${e.provider.packageName}"))
if (intent.resolveActivity(context.packageManager) != null)
notify .setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
.setAutoCancel(true)
nm.notify(Constants.NOTIFICATION_TASK_SYNC, notify.build())
syncResult.databaseError = true
} catch (e: Exception) {
Logger.log.log(Level.SEVERE, "Couldn't sync task lists", e)
syncResult.databaseError = true
}
Logger.log.info("Task sync complete")
......
......@@ -274,6 +274,8 @@
</plurals>
<string name="sync_error_permissions">DAVdroid permissions</string>
<string name="sync_error_permissions_text">Additional permissions required</string>
<string name="sync_error_opentasks_too_old">OpenTasks too old</string>
<string name="sync_error_opentasks_required_version">Required version: %1$s (currently %2$s)</string>
<string name="sync_error_calendar">Calendar synchronization failed (%s)</string>
<string name="sync_error_contacts">Address book synchronization failed (%s)</string>
<string name="sync_error_tasks">Task synchronization failed (%s)</string>
......
Subproject commit bff8e5b8857605da0ac754c99eaed603a71f7bcb
Subproject commit d0adb639daa2237914dca693e858d20ddb60c69e
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment