mirror of
https://github.com/etesync/android
synced 2024-11-14 03:39:52 +00:00
Add Tasks.org support
This commit is contained in:
parent
a81973f816
commit
e01f54c687
@ -110,6 +110,19 @@
|
||||
android:resource="@xml/sync_tasks"/>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".syncadapter.TasksOrgSyncAdapterService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/sync_tasks_org"/>
|
||||
</service>
|
||||
|
||||
|
||||
<!-- Address book account -->
|
||||
<service
|
||||
|
@ -24,6 +24,7 @@ import android.provider.ContactsContract
|
||||
import androidx.core.content.ContextCompat
|
||||
import at.bitfire.ical4android.AndroidCalendar
|
||||
import at.bitfire.ical4android.CalendarStorageException
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.vcard4android.ContactsStorageException
|
||||
import com.etesync.syncadapter.log.Logger
|
||||
import com.etesync.syncadapter.model.*
|
||||
@ -85,8 +86,10 @@ class App : Application() {
|
||||
tasksFilter.addDataScheme("package")
|
||||
registerReceiver(PackageChangedReceiver(), tasksFilter)
|
||||
|
||||
// check whether a tasks app is currently installed
|
||||
PackageChangedReceiver.updateTaskSync(this@App)
|
||||
OPENTASK_PROVIDERS.forEach {
|
||||
// check whether a tasks app is currently installed
|
||||
PackageChangedReceiver.updateTaskSync(this@App, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.provider.CalendarContract
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.ProviderName
|
||||
import com.etesync.syncadapter.log.Logger
|
||||
import com.etesync.syncadapter.resource.LocalTaskList
|
||||
|
||||
@ -23,15 +24,18 @@ class PackageChangedReceiver : BroadcastReceiver() {
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (Intent.ACTION_PACKAGE_ADDED == intent.action || Intent.ACTION_PACKAGE_FULLY_REMOVED == intent.action)
|
||||
updateTaskSync(context)
|
||||
if (Intent.ACTION_PACKAGE_ADDED == intent.action || Intent.ACTION_PACKAGE_FULLY_REMOVED == intent.action) {
|
||||
TaskProvider.OPENTASK_PROVIDERS.forEach {
|
||||
updateTaskSync(context, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun updateTaskSync(context: Context) {
|
||||
val tasksInstalled = LocalTaskList.tasksProviderAvailable(context)
|
||||
Logger.log.info("Package (un)installed; OpenTasks provider now available = $tasksInstalled")
|
||||
internal fun updateTaskSync(context: Context, provider: ProviderName) {
|
||||
val tasksInstalled = LocalTaskList.tasksProviderAvailable(context, provider)
|
||||
Logger.log.info("Package (un)installed; ${provider.name} provider now available = $tasksInstalled")
|
||||
|
||||
for (account in AccountManager.get(context).getAccountsByType(App.accountType)) {
|
||||
val settings = AccountSettings(context, account)
|
||||
@ -40,12 +44,12 @@ class PackageChangedReceiver : BroadcastReceiver() {
|
||||
if (tasksInstalled) {
|
||||
if (calendarSyncInterval == null) {
|
||||
// do nothing atm
|
||||
} else if (ContentResolver.getIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority) <= 0) {
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 1)
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, calendarSyncInterval)
|
||||
} else if (ContentResolver.getIsSyncable(account, provider.authority) <= 0) {
|
||||
ContentResolver.setIsSyncable(account, provider.authority, 1)
|
||||
settings.setSyncInterval(provider.authority, calendarSyncInterval)
|
||||
}
|
||||
} else {
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 0)
|
||||
ContentResolver.setIsSyncable(account, provider.authority, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import at.bitfire.ical4android.AndroidTaskList
|
||||
import at.bitfire.ical4android.AndroidTaskListFactory
|
||||
import at.bitfire.ical4android.CalendarStorageException
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.ProviderName
|
||||
import com.etesync.syncadapter.model.JournalEntity
|
||||
import org.dmfs.tasks.contract.TaskContract.TaskLists
|
||||
import org.dmfs.tasks.contract.TaskContract.Tasks
|
||||
@ -30,12 +31,12 @@ class LocalTaskList private constructor(
|
||||
companion object {
|
||||
val defaultColor = -0x743cb6 // light green 500
|
||||
|
||||
fun tasksProviderAvailable(context: Context): Boolean {
|
||||
fun tasksProviderAvailable(context: Context, provider: ProviderName): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
return context.packageManager.resolveContentProvider(TaskProvider.ProviderName.OpenTasks.authority, 0) != null
|
||||
return context.packageManager.resolveContentProvider(provider.authority, 0) != null
|
||||
else {
|
||||
try {
|
||||
TaskProvider.acquire(context, TaskProvider.ProviderName.OpenTasks)?.use {
|
||||
TaskProvider.acquire(context, provider)?.use {
|
||||
return true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -4,12 +4,13 @@ import android.accounts.Account
|
||||
import android.content.ContentResolver
|
||||
import android.os.Bundle
|
||||
import android.provider.CalendarContract
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import com.etesync.syncadapter.App
|
||||
|
||||
|
||||
fun requestSync(account: Account?) {
|
||||
val authorities = arrayOf(App.addressBooksAuthority, CalendarContract.AUTHORITY, TaskProvider.ProviderName.OpenTasks.authority)
|
||||
val authorities = arrayOf(App.addressBooksAuthority, CalendarContract.AUTHORITY) +
|
||||
OPENTASK_PROVIDERS.map { it.authority }
|
||||
|
||||
for (authority in authorities) {
|
||||
val extras = Bundle()
|
||||
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright © Ricki Hirner (bitfire web engineering).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Public License v3.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
package com.etesync.syncadapter.syncadapter
|
||||
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
|
||||
/**
|
||||
* Synchronization manager for CalDAV collections; handles tasks ({@code VTODO}).
|
||||
*/
|
||||
class TasksOrgSyncAdapterService: SyncAdapterService() {
|
||||
|
||||
override fun syncAdapter() =
|
||||
TasksSyncAdapterService.TasksSyncAdapter(this, TaskProvider.ProviderName.TasksOrg)
|
||||
|
||||
}
|
@ -17,6 +17,7 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import at.bitfire.ical4android.AndroidTaskList
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.ProviderName
|
||||
import com.etesync.syncadapter.AccountSettings
|
||||
import com.etesync.syncadapter.App
|
||||
import com.etesync.syncadapter.Constants
|
||||
@ -35,18 +36,18 @@ import java.util.*
|
||||
*/
|
||||
class TasksSyncAdapterService: SyncAdapterService() {
|
||||
|
||||
override fun syncAdapter() = TasksSyncAdapter(this)
|
||||
|
||||
override fun syncAdapter() = TasksSyncAdapter(this, ProviderName.OpenTasks)
|
||||
|
||||
class TasksSyncAdapter(
|
||||
context: Context
|
||||
context: Context,
|
||||
private val name: ProviderName
|
||||
): SyncAdapter(context) {
|
||||
override val syncErrorTitle = R.string.sync_error_tasks
|
||||
override val notificationManager = SyncNotification(context, "journals-tasks", Constants.NOTIFICATION_TASK_SYNC)
|
||||
|
||||
override fun onPerformSyncDo(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) {
|
||||
|
||||
val taskProvider = TaskProvider.fromProviderClient(context, provider)
|
||||
val taskProvider = TaskProvider.fromProviderClient(context, provider, name)
|
||||
|
||||
// make sure account can be seen by OpenTasks
|
||||
if (Build.VERSION.SDK_INT >= 26)
|
||||
|
@ -26,6 +26,7 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.vcard4android.ContactsStorageException
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.journalmanager.Crypto
|
||||
@ -378,7 +379,9 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe
|
||||
info.taskdav = AccountInfo.ServiceInfo()
|
||||
info.taskdav!!.id = id
|
||||
info.taskdav!!.refreshing = davService != null && davService!!.isRefreshing(id) ||
|
||||
ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority)
|
||||
OPENTASK_PROVIDERS.any {
|
||||
ContentResolver.isSyncActive(account, it.authority)
|
||||
}
|
||||
info.taskdav!!.journals = JournalEntity.getJournals(data, serviceEntity)
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import androidx.loader.content.AsyncTaskLoader
|
||||
import androidx.loader.content.Loader
|
||||
import androidx.preference.*
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.syncadapter.Constants.KEY_ACCOUNT
|
||||
import com.etesync.syncadapter.R
|
||||
@ -121,7 +122,9 @@ class AccountSettingsActivity : BaseActivity() {
|
||||
val newInterval = java.lang.Long.parseLong(newValue as String)
|
||||
settings.setSyncInterval(App.addressBooksAuthority, newInterval)
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, newInterval)
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, newInterval)
|
||||
OPENTASK_PROVIDERS.forEach {
|
||||
settings.setSyncInterval(it.authority, newInterval)
|
||||
}
|
||||
loaderManager.restartLoader(0, arguments, this@AccountSettingsFragment)
|
||||
false
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import androidx.loader.app.LoaderManager
|
||||
import androidx.loader.content.AsyncTaskLoader
|
||||
import androidx.loader.content.Loader
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.journalmanager.Crypto
|
||||
import com.etesync.journalmanager.Exceptions
|
||||
@ -84,15 +85,14 @@ class CreateCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks
|
||||
|
||||
override fun loadInBackground(): Exception? {
|
||||
try {
|
||||
var authority: String = ""
|
||||
|
||||
val data = (context.applicationContext as App).data
|
||||
|
||||
// 1. find service ID
|
||||
when (info.enumType){
|
||||
CollectionInfo.Type.ADDRESS_BOOK -> authority = App.addressBooksAuthority
|
||||
CollectionInfo.Type.CALENDAR -> authority = CalendarContract.AUTHORITY
|
||||
CollectionInfo.Type.TASKS -> authority = TaskProvider.ProviderName.OpenTasks.authority
|
||||
val authorities = when (info.enumType){
|
||||
CollectionInfo.Type.ADDRESS_BOOK -> listOf(App.addressBooksAuthority)
|
||||
CollectionInfo.Type.CALENDAR -> listOf(CalendarContract.AUTHORITY)
|
||||
CollectionInfo.Type.TASKS -> OPENTASK_PROVIDERS.map { it.authority }
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
val serviceEntity = JournalModel.Service.fetchOrCreate(data, account.name, info.enumType)
|
||||
@ -127,7 +127,7 @@ class CreateCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks
|
||||
journalManager.update(journal)
|
||||
}
|
||||
|
||||
requestSync(authority)
|
||||
authorities.forEach { requestSync(it) }
|
||||
} catch (e: IllegalStateException) {
|
||||
return e
|
||||
} catch (e: Exceptions.HttpException) {
|
||||
|
@ -25,6 +25,7 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import at.bitfire.ical4android.TaskProvider.ProviderName
|
||||
import at.bitfire.vcard4android.ContactsStorageException
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.syncadapter.Constants.KEY_ACCOUNT
|
||||
@ -156,7 +157,7 @@ class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String>
|
||||
.append(if (powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID)) "yes" else "no")
|
||||
.append("\n")
|
||||
// permissions
|
||||
for (permission in arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR, PermissionsActivity.PERMISSION_READ_TASKS, PermissionsActivity.PERMISSION_WRITE_TASKS))
|
||||
for (permission in arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR) + ProviderName.OpenTasks.permissions + ProviderName.TasksOrg.permissions)
|
||||
report.append(permission).append(" permission: ")
|
||||
.append(if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) "granted" else "denied")
|
||||
.append("\n")
|
||||
@ -169,7 +170,7 @@ class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String>
|
||||
for (acct in accountManager.getAccountsByType(context.getString(R.string.account_type)))
|
||||
try {
|
||||
val settings = AccountSettings(context, acct)
|
||||
report.append("Account: ").append(acct.name).append("\n" + " Address book sync. interval: ").append(syncStatus(settings, App.addressBooksAuthority)).append("\n" + " Calendar sync. interval: ").append(syncStatus(settings, CalendarContract.AUTHORITY)).append("\n" + " OpenTasks sync. interval: ").append(syncStatus(settings, "org.dmfs.tasks")).append("\n" + " WiFi only: ").append(settings.syncWifiOnly)
|
||||
report.append("Account: ").append(acct.name).append("\n" + " Address book sync. interval: ").append(syncStatus(settings, App.addressBooksAuthority)).append("\n" + " Calendar sync. interval: ").append(syncStatus(settings, CalendarContract.AUTHORITY)).append("\n" + " OpenTasks sync. interval: ").append(syncStatus(settings, ProviderName.OpenTasks.authority)).append("\n" + " Tasks.org sync. interval: ").append(syncStatus(settings, ProviderName.TasksOrg.authority)).append("\n" + " WiFi only: ").append(settings.syncWifiOnly)
|
||||
if (settings.syncWifiOnlySSID != null)
|
||||
report.append(", SSID: ").append(settings.syncWifiOnlySSID)
|
||||
report.append("\n [CardDAV] Contact group method: ").append(settings.groupMethod)
|
||||
|
@ -19,6 +19,7 @@ import at.bitfire.ical4android.Event
|
||||
import at.bitfire.ical4android.InvalidCalendarException
|
||||
import at.bitfire.ical4android.Task
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.vcard4android.Contact
|
||||
import com.etesync.syncadapter.App
|
||||
import com.etesync.syncadapter.Constants
|
||||
@ -116,15 +117,17 @@ class JournalItemActivity : BaseActivity(), Refreshable {
|
||||
}
|
||||
}
|
||||
CollectionInfo.Type.TASKS -> {
|
||||
val provider = TaskProvider.acquire(this, TaskProvider.ProviderName.OpenTasks)!!
|
||||
val localTaskList = LocalTaskList.findByName(account, provider, LocalTaskList.Factory, info.uid!!)!!
|
||||
val task = Task.tasksFromReader(StringReader(syncEntry.content))[0]
|
||||
var localTask = localTaskList.findByUid(task.uid!!)
|
||||
if (localTask != null) {
|
||||
localTask.updateAsDirty(task)
|
||||
} else {
|
||||
localTask = LocalTask(localTaskList, task, task.uid, null)
|
||||
localTask.addAsDirty()
|
||||
OPENTASK_PROVIDERS.forEach {
|
||||
val provider = TaskProvider.acquire(this, it)!!
|
||||
val localTaskList = LocalTaskList.findByName(account, provider, LocalTaskList.Factory, info.uid!!)!!
|
||||
val task = Task.tasksFromReader(StringReader(syncEntry.content))[0]
|
||||
var localTask = localTaskList.findByUid(task.uid!!)
|
||||
if (localTask != null) {
|
||||
localTask.updateAsDirty(task)
|
||||
} else {
|
||||
localTask = LocalTask(localTaskList, task, task.uid, null)
|
||||
localTask.addAsDirty()
|
||||
}
|
||||
}
|
||||
}
|
||||
CollectionInfo.Type.ADDRESS_BOOK -> {
|
||||
|
@ -13,8 +13,11 @@ import android.app.Activity
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.ical4android.TaskProvider.ProviderName
|
||||
import com.etesync.syncadapter.Constants
|
||||
import com.etesync.syncadapter.R
|
||||
import com.etesync.syncadapter.resource.LocalTaskList
|
||||
@ -38,16 +41,10 @@ class PermissionsActivity : BaseActivity() {
|
||||
val noContactsPermissions = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED
|
||||
findViewById<View>(R.id.contacts_permissions).visibility = if (noContactsPermissions) View.VISIBLE else View.GONE
|
||||
|
||||
val noTaskPermissions: Boolean
|
||||
if (LocalTaskList.tasksProviderAvailable(this)) {
|
||||
noTaskPermissions = ActivityCompat.checkSelfPermission(this, PERMISSION_READ_TASKS) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, PERMISSION_WRITE_TASKS) != PackageManager.PERMISSION_GRANTED
|
||||
findViewById<View>(R.id.opentasks_permissions).visibility = if (noTaskPermissions) View.VISIBLE else View.GONE
|
||||
} else {
|
||||
findViewById<View>(R.id.opentasks_permissions).visibility = View.GONE
|
||||
noTaskPermissions = false
|
||||
}
|
||||
val needOpenTaskPermissions = setupPermissions(ProviderName.OpenTasks, R.id.opentasks_permissions)
|
||||
val needTasksOrgPermissions = setupPermissions(ProviderName.TasksOrg, R.id.tasksorg_permissions)
|
||||
|
||||
if (!noCalendarPermissions && !noContactsPermissions && !noTaskPermissions) {
|
||||
if (!noCalendarPermissions && !noContactsPermissions && !(needOpenTaskPermissions || needTasksOrgPermissions)) {
|
||||
val nm = NotificationManagerCompat.from(this)
|
||||
nm.cancel(Constants.NOTIFICATION_PERMISSIONS)
|
||||
|
||||
@ -55,6 +52,15 @@ class PermissionsActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPermissions(provider: ProviderName, @IdRes id: Int): Boolean {
|
||||
val providerAvailable = LocalTaskList.tasksProviderAvailable(this, provider)
|
||||
val hasPermissions = providerAvailable && provider.permissions.all {
|
||||
ActivityCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
findViewById<View>(id).visibility = if (hasPermissions) View.GONE else View.VISIBLE
|
||||
return providerAvailable && !hasPermissions
|
||||
}
|
||||
|
||||
fun requestCalendarPermissions(v: View) {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR), 0)
|
||||
}
|
||||
@ -64,7 +70,11 @@ class PermissionsActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
fun requestOpenTasksPermissions(v: View) {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(PERMISSION_READ_TASKS, PERMISSION_WRITE_TASKS), 0)
|
||||
ActivityCompat.requestPermissions(this, ProviderName.OpenTasks.permissions, 0)
|
||||
}
|
||||
|
||||
fun requestTasksOrgPermissions(v: View) {
|
||||
ActivityCompat.requestPermissions(this, ProviderName.TasksOrg.permissions, 0)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||
@ -75,11 +85,8 @@ class PermissionsActivity : BaseActivity() {
|
||||
companion object {
|
||||
private val REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124
|
||||
|
||||
val PERMISSION_READ_TASKS = "org.dmfs.permission.READ_TASKS"
|
||||
val PERMISSION_WRITE_TASKS = "org.dmfs.permission.WRITE_TASKS"
|
||||
|
||||
fun requestAllPermissions(activity: Activity) {
|
||||
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS, PERMISSION_READ_TASKS, PERMISSION_WRITE_TASKS), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)
|
||||
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS) + OPENTASK_PROVIDERS.flatMap { it.permissions.toList() }, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import at.bitfire.ical4android.CalendarStorageException
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.vcard4android.ContactsStorageException
|
||||
import com.etesync.syncadapter.App
|
||||
import com.etesync.syncadapter.Constants
|
||||
@ -212,7 +213,9 @@ class ViewCollectionActivity : BaseActivity(), Refreshable {
|
||||
}
|
||||
CollectionInfo.Type.TASKS -> {
|
||||
try {
|
||||
val providerClient = TaskProvider.acquire(this@ViewCollectionActivity, TaskProvider.ProviderName.OpenTasks)
|
||||
val providerClient = OPENTASK_PROVIDERS.mapNotNull {
|
||||
TaskProvider.acquire(this@ViewCollectionActivity, it)
|
||||
}.firstOrNull()
|
||||
if (providerClient == null) {
|
||||
return null
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import android.provider.CalendarContract
|
||||
import android.provider.ContactsContract
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import at.bitfire.ical4android.*
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import at.bitfire.vcard4android.BatchOperation
|
||||
import at.bitfire.vcard4android.Contact
|
||||
import at.bitfire.vcard4android.ContactsStorageException
|
||||
@ -282,40 +283,44 @@ class ImportFragment : DialogFragment() {
|
||||
|
||||
finishParsingFile(tasks.size)
|
||||
|
||||
val provider = TaskProvider.acquire(context, TaskProvider.ProviderName.OpenTasks)
|
||||
if (provider == null) {
|
||||
val providers = OPENTASK_PROVIDERS.mapNotNull {
|
||||
TaskProvider.acquire(context, it)
|
||||
}
|
||||
if (providers.isEmpty()) {
|
||||
result.e = Exception("Failed to acquire tasks content provider.")
|
||||
return result
|
||||
}
|
||||
|
||||
val localTaskList: LocalTaskList?
|
||||
try {
|
||||
localTaskList = LocalTaskList.findByName(account, provider, LocalTaskList.Factory, info.uid!!)
|
||||
if (localTaskList == null) {
|
||||
throw FileNotFoundException("Failed to load local resource.")
|
||||
}
|
||||
} catch (e: FileNotFoundException) {
|
||||
Logger.log.info("Fail" + e.localizedMessage)
|
||||
result.e = e
|
||||
return result
|
||||
}
|
||||
|
||||
for (task in tasks) {
|
||||
providers.forEach {
|
||||
val localTaskList: LocalTaskList?
|
||||
try {
|
||||
var localTask = localTaskList.findByUid(task.uid!!)
|
||||
if (localTask != null) {
|
||||
localTask.updateAsDirty(task)
|
||||
result.updated++
|
||||
} else {
|
||||
localTask = LocalTask(localTaskList, task, task.uid, null)
|
||||
localTask.addAsDirty()
|
||||
result.added++
|
||||
localTaskList = LocalTaskList.findByName(account, it, LocalTaskList.Factory, info.uid!!)
|
||||
if (localTaskList == null) {
|
||||
throw FileNotFoundException("Failed to load local resource.")
|
||||
}
|
||||
} catch (e: CalendarStorageException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: FileNotFoundException) {
|
||||
Logger.log.info("Fail" + e.localizedMessage)
|
||||
result.e = e
|
||||
return result
|
||||
}
|
||||
|
||||
entryProcessed()
|
||||
for (task in tasks) {
|
||||
try {
|
||||
var localTask = localTaskList.findByUid(task.uid!!)
|
||||
if (localTask != null) {
|
||||
localTask.updateAsDirty(task)
|
||||
result.updated++
|
||||
} else {
|
||||
localTask = LocalTask(localTaskList, task, task.uid, null)
|
||||
localTask.addAsDirty()
|
||||
result.added++
|
||||
}
|
||||
} catch (e: CalendarStorageException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
entryProcessed()
|
||||
}
|
||||
}
|
||||
} else if (info.enumType == CollectionInfo.Type.ADDRESS_BOOK) {
|
||||
val uidToLocalId = HashMap<String?, Long>()
|
||||
|
@ -21,6 +21,7 @@ import android.provider.CalendarContract
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import at.bitfire.ical4android.TaskProvider
|
||||
import at.bitfire.ical4android.TaskProvider.Companion.OPENTASK_PROVIDERS
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.journalmanager.Crypto
|
||||
import com.etesync.journalmanager.Exceptions
|
||||
@ -153,11 +154,13 @@ class SetupEncryptionFragment : DialogFragment() {
|
||||
// calendar sync is automatically enabled by isAlwaysSyncable="true" in res/xml/sync_contacts.xml
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, Constants.DEFAULT_SYNC_INTERVAL.toLong())
|
||||
|
||||
// enable task sync if OpenTasks is installed
|
||||
// further changes will be handled by PackageChangedReceiver
|
||||
if (LocalTaskList.tasksProviderAvailable(context!!)) {
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 1)
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, Constants.DEFAULT_SYNC_INTERVAL.toLong())
|
||||
OPENTASK_PROVIDERS.forEach {
|
||||
// enable task sync if OpenTasks is installed
|
||||
// further changes will be handled by PackageChangedReceiver
|
||||
if (LocalTaskList.tasksProviderAvailable(context!!, it)) {
|
||||
ContentResolver.setIsSyncable(account, it.authority, 1)
|
||||
settings.setSyncInterval(it.authority, Constants.DEFAULT_SYNC_INTERVAL.toLong())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 0)
|
||||
|
@ -77,6 +77,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="16dp"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<TextView
|
||||
@ -98,6 +99,31 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tasksorg_permissions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextView.Heading"
|
||||
android:text="@string/permissions_tasks_org"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/permissions_tasks_org_details"/>
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/permissions_tasks_org_request"
|
||||
android:onClick="requestTasksOrgPermissions"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -196,6 +196,9 @@
|
||||
<string name="permissions_opentasks">OpenTasks permissions</string>
|
||||
<string name="permissions_opentasks_details">To synchronize tasks with your local task lists, EteSync needs to access OpenTasks.</string>
|
||||
<string name="permissions_opentasks_request">Request OpenTasks permissions</string>
|
||||
<string name="permissions_tasks_org">Tasks.org permissions</string>
|
||||
<string name="permissions_tasks_org_details">To synchronize tasks with your local task lists, EteSync needs to access Tasks.org.</string>
|
||||
<string name="permissions_tasks_org_request">Request Tasks.org permissions</string>
|
||||
|
||||
<!-- AddAccountActivity -->
|
||||
<string name="login_title">Add account</string>
|
||||
|
12
app/src/main/res/xml/sync_tasks_org.xml
Normal file
12
app/src/main/res/xml/sync_tasks_org.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<!--
|
||||
~ Copyright © Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accountType="@string/account_type"
|
||||
android:contentAuthority="org.tasks.opentasks"
|
||||
android:supportsUploading="true" />
|
@ -1 +1 @@
|
||||
Subproject commit c0459f905571ab2e08e8af9ac40a96200d8cb862
|
||||
Subproject commit 0a070c7866792756d90be429522127ef9108eff8
|
Loading…
Reference in New Issue
Block a user