mirror of
https://github.com/etesync/android
synced 2025-01-25 15:10:55 +00:00
Update local calendars according to ServiceDB at sync
This commit is contained in:
parent
5025a61cd1
commit
f32493986b
@ -42,6 +42,7 @@ import at.bitfire.ical4android.CalendarStorageException;
|
|||||||
import at.bitfire.ical4android.DateUtils;
|
import at.bitfire.ical4android.DateUtils;
|
||||||
import at.bitfire.vcard4android.ContactsStorageException;
|
import at.bitfire.vcard4android.ContactsStorageException;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||||
|
|
||||||
@ -69,12 +70,17 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
|||||||
super(account, provider, LocalEvent.Factory.INSTANCE, id);
|
super(account, provider, LocalEvent.Factory.INSTANCE, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(15)
|
public static Uri create(@NonNull Account account, @NonNull ContentProviderClient provider, @NonNull CollectionInfo info) throws CalendarStorageException {
|
||||||
public static Uri create(Account account, ContentResolver resolver, CollectionInfo info) throws CalendarStorageException {
|
ContentValues values = valuesFromCollectionInfo(info);
|
||||||
@Cleanup("release") ContentProviderClient provider = resolver.acquireContentProviderClient(CalendarContract.AUTHORITY);
|
values.put(Calendars.OWNER_ACCOUNT, account.name);
|
||||||
if (provider == null)
|
return create(account, provider, values);
|
||||||
throw new CalendarStorageException("Couldn't acquire ContentProviderClient for " + CalendarContract.AUTHORITY);
|
}
|
||||||
|
|
||||||
|
public void update(CollectionInfo info) throws CalendarStorageException {
|
||||||
|
update(valuesFromCollectionInfo(info));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ContentValues valuesFromCollectionInfo(CollectionInfo info) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Calendars.NAME, info.url);
|
values.put(Calendars.NAME, info.url);
|
||||||
values.put(Calendars.CALENDAR_DISPLAY_NAME, info.displayName);
|
values.put(Calendars.CALENDAR_DISPLAY_NAME, info.displayName);
|
||||||
@ -88,7 +94,6 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
|||||||
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1);
|
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
values.put(Calendars.OWNER_ACCOUNT, account.name);
|
|
||||||
values.put(Calendars.SYNC_EVENTS, 1);
|
values.put(Calendars.SYNC_EVENTS, 1);
|
||||||
values.put(Calendars.VISIBLE, 1);
|
values.put(Calendars.VISIBLE, 1);
|
||||||
if (!TextUtils.isEmpty(info.timeZone)) {
|
if (!TextUtils.isEmpty(info.timeZone)) {
|
||||||
@ -101,7 +106,7 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
|||||||
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(new int[] { Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY }, ","));
|
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(new int[] { Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY }, ","));
|
||||||
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(new int[] { CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE }, ", "));
|
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(new int[] { CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE }, ", "));
|
||||||
}
|
}
|
||||||
return create(account, provider, values);
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,30 +11,42 @@ import android.accounts.Account;
|
|||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.AbstractThreadedSyncAdapter;
|
import android.content.AbstractThreadedSyncAdapter;
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SyncResult;
|
import android.content.SyncResult;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.DatabaseUtils;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.provider.CalendarContract;
|
import android.provider.CalendarContract;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
|
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
||||||
import at.bitfire.davdroid.resource.LocalCalendar;
|
import at.bitfire.davdroid.resource.LocalCalendar;
|
||||||
import at.bitfire.ical4android.CalendarStorageException;
|
import at.bitfire.ical4android.CalendarStorageException;
|
||||||
|
import lombok.Cleanup;
|
||||||
|
|
||||||
public class CalendarsSyncAdapterService extends Service {
|
public class CalendarsSyncAdapterService extends Service {
|
||||||
private static SyncAdapter syncAdapter;
|
private static SyncAdapter syncAdapter;
|
||||||
|
OpenHelper dbHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
if (syncAdapter == null)
|
dbHelper = new OpenHelper(this);
|
||||||
syncAdapter = new SyncAdapter(getApplicationContext());
|
syncAdapter = new SyncAdapter(this, dbHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
syncAdapter = null;
|
dbHelper.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
@ -43,8 +55,14 @@ public class CalendarsSyncAdapterService extends Service {
|
|||||||
|
|
||||||
|
|
||||||
private static class SyncAdapter extends AbstractThreadedSyncAdapter {
|
private static class SyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
public SyncAdapter(Context context) {
|
private final OpenHelper dbHelper;
|
||||||
|
private final SQLiteDatabase db;
|
||||||
|
|
||||||
|
public SyncAdapter(Context context, OpenHelper dbHelper) {
|
||||||
super(context, false);
|
super(context, false);
|
||||||
|
|
||||||
|
this.dbHelper = dbHelper;
|
||||||
|
db = dbHelper.getReadableDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,6 +70,8 @@ public class CalendarsSyncAdapterService extends Service {
|
|||||||
Constants.log.info("Starting calendar sync (" + authority + ")");
|
Constants.log.info("Starting calendar sync (" + authority + ")");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
updateLocalCalendars(provider, account);
|
||||||
|
|
||||||
for (LocalCalendar calendar : (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
|
for (LocalCalendar calendar : (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
|
||||||
Constants.log.info("Synchronizing calendar #" + calendar.getId() + ", URL: " + calendar.getName());
|
Constants.log.info("Synchronizing calendar #" + calendar.getId() + ", URL: " + calendar.getName());
|
||||||
CalendarSyncManager syncManager = new CalendarSyncManager(getContext(), account, extras, authority, syncResult, calendar);
|
CalendarSyncManager syncManager = new CalendarSyncManager(getContext(), account, extras, authority, syncResult, calendar);
|
||||||
@ -59,10 +79,64 @@ public class CalendarsSyncAdapterService extends Service {
|
|||||||
}
|
}
|
||||||
} catch (CalendarStorageException e) {
|
} catch (CalendarStorageException e) {
|
||||||
Constants.log.error("Couldn't enumerate local calendars", e);
|
Constants.log.error("Couldn't enumerate local calendars", e);
|
||||||
|
} finally {
|
||||||
|
dbHelper.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Constants.log.info("Calendar sync complete");
|
Constants.log.info("Calendar sync complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLocalCalendars(ContentProviderClient provider, Account account) throws CalendarStorageException {
|
||||||
|
long service = getService(account);
|
||||||
|
|
||||||
|
// enumerate remote and local calendars
|
||||||
|
Map<String, CollectionInfo> remote = remoteCalendars(service);
|
||||||
|
LocalCalendar[] local = (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null);
|
||||||
|
|
||||||
|
// delete obsolete local calendar
|
||||||
|
for (LocalCalendar calendar : local) {
|
||||||
|
String url = calendar.getName();
|
||||||
|
if (!remote.containsKey(url)) {
|
||||||
|
Constants.log.debug("Deleting obsolete local calendar {}", url);
|
||||||
|
calendar.delete();
|
||||||
|
} else {
|
||||||
|
// remote CollectionInfo found for this local collection, update data
|
||||||
|
CollectionInfo info = remote.get(url);
|
||||||
|
Constants.log.debug("Updating local calendar {} with {}", url, info);
|
||||||
|
calendar.update(info);
|
||||||
|
// we already have a local calendar for this remote collection, don't take into consideration anymore
|
||||||
|
remote.remove(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new local calendars
|
||||||
|
for (String url : remote.keySet()) {
|
||||||
|
CollectionInfo info = remote.get(url);
|
||||||
|
Constants.log.info("Adding local calendar list {}", info);
|
||||||
|
LocalCalendar.create(account, provider, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long getService(Account account) {
|
||||||
|
@Cleanup Cursor c = db.query(ServiceDB.Services._TABLE, new String[]{ServiceDB.Services.ID},
|
||||||
|
ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?", new String[]{account.name, ServiceDB.Services.SERVICE_CALDAV}, null, null, null);
|
||||||
|
c.moveToNext();
|
||||||
|
return c.getLong(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, CollectionInfo> remoteCalendars(long service) {
|
||||||
|
Map<String, CollectionInfo> collections = new LinkedHashMap<>();
|
||||||
|
@Cleanup Cursor cursor = db.query(ServiceDB.Collections._TABLE, ServiceDB.Collections._COLUMNS,
|
||||||
|
ServiceDB.Collections.SERVICE_ID + "=? AND " + ServiceDB.Collections.SUPPORTS_VEVENT + "!=0",
|
||||||
|
new String[] { String.valueOf(service) }, null, null, null);
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
DatabaseUtils.cursorRowToContentValues(cursor, values);
|
||||||
|
CollectionInfo info = CollectionInfo.fromDB(values);
|
||||||
|
collections.put(info.url, info);
|
||||||
|
}
|
||||||
|
return collections;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ public class TasksSyncAdapterService extends Service {
|
|||||||
|
|
||||||
|
|
||||||
private static class SyncAdapter extends AbstractThreadedSyncAdapter {
|
private static class SyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
final OpenHelper dbHelper;
|
private final OpenHelper dbHelper;
|
||||||
final SQLiteDatabase db;
|
private final SQLiteDatabase db;
|
||||||
|
|
||||||
public SyncAdapter(Context context, OpenHelper dbHelper) {
|
public SyncAdapter(Context context, OpenHelper dbHelper) {
|
||||||
super(context, false);
|
super(context, false);
|
||||||
|
@ -323,6 +323,9 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
|||||||
|
|
||||||
CollectionInfo info = getItem(position);
|
CollectionInfo info = getItem(position);
|
||||||
|
|
||||||
|
View vColor = v.findViewById(R.id.color);
|
||||||
|
vColor.setBackgroundColor(info.color);
|
||||||
|
|
||||||
TextView tv = (TextView)v.findViewById(R.id.title);
|
TextView tv = (TextView)v.findViewById(R.id.title);
|
||||||
tv.setText(TextUtils.isEmpty(info.displayName) ? info.url : info.displayName);
|
tv.setText(TextUtils.isEmpty(info.displayName) ? info.url : info.displayName);
|
||||||
|
|
||||||
|
@ -20,6 +20,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="4dp"/>
|
android:layout_marginRight="4dp"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/color"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
tools:background="@color/davdroid_green_dark"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
Loading…
Reference in New Issue
Block a user