Tue, 10 Feb 2015 18:12:00 +0100
Import initial revisions of existing project AndroidCaldavSyncAdapater,
forked from upstream repository at 27e8a0f8495c92e0780d450bdf0c7cec77a03a55.
1 /**
2 * Copyright (c) 2012-2013, Gerald Garcia, David Wiesner, Timo Berger
3 *
4 * This file is part of Andoid Caldav Sync Adapter Free.
5 *
6 * Andoid Caldav Sync Adapter Free is free software: you can redistribute
7 * it and/or modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation, either version 3 of the
9 * License, or at your option any later version.
10 *
11 * Andoid Caldav Sync Adapter Free is distributed in the hope that
12 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Andoid Caldav Sync Adapter Free.
18 * If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
22 package org.gege.caldavsyncadapter.syncadapter;
24 import java.io.IOException;
25 import java.net.URI;
26 //import java.net.MalformedURLException;
27 import java.net.URISyntaxException;
28 import java.util.ArrayList;
29 //import java.security.GeneralSecurityException;
31 import javax.xml.parsers.ParserConfigurationException;
33 import net.fortuna.ical4j.data.ParserException;
35 import org.apache.http.ParseException;
36 import org.apache.http.client.ClientProtocolException;
37 import org.gege.caldavsyncadapter.Event;
38 import org.gege.caldavsyncadapter.android.entities.AndroidEvent;
39 import org.gege.caldavsyncadapter.authenticator.AuthenticatorActivity;
40 import org.gege.caldavsyncadapter.caldav.CaldavFacade;
41 import org.gege.caldavsyncadapter.caldav.CaldavProtocolException;
42 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar;
43 import org.gege.caldavsyncadapter.caldav.entities.CalendarEvent;
44 import org.gege.caldavsyncadapter.caldav.entities.CalendarList;
45 import org.gege.caldavsyncadapter.caldav.entities.DavCalendar.CalendarSource;
46 import org.gege.caldavsyncadapter.syncadapter.notifications.NotificationsHelper;
47 import org.xml.sax.SAXException;
49 import android.accounts.Account;
50 import android.accounts.AccountManager;
51 import android.content.AbstractThreadedSyncAdapter;
52 import android.content.ContentProviderClient;
53 import android.content.ContentUris;
54 import android.content.ContentValues;
55 import android.content.Context;
56 import android.content.SyncResult;
57 import android.content.SyncStats;
58 import android.content.pm.PackageManager.NameNotFoundException;
59 import android.database.Cursor;
60 import android.net.Uri;
61 import android.os.Bundle;
62 import android.os.RemoteException;
63 import android.provider.CalendarContract.Attendees;
64 import android.provider.CalendarContract.Calendars;
65 import android.provider.CalendarContract.Events;
66 import android.provider.CalendarContract.Reminders;
67 import android.util.Log;
69 public class SyncAdapter extends AbstractThreadedSyncAdapter {
71 private static final String TAG = "SyncAdapter";
72 private AccountManager mAccountManager;
73 private String mVersion = "";
74 private int mCountPerformSync = 0;
75 private int mCountSyncCanceled = 0;
76 private int mCountProviderFailed = 0;
78 private int mCountProviderFailedMax = 3;
79 // private Context mContext;
82 /* private static final String[] CALENDAR_PROJECTION = new String[] {
83 Calendars._ID, // 0
84 Calendars.ACCOUNT_NAME, // 1
85 Calendars.CALENDAR_DISPLAY_NAME, // 2
86 Calendars.OWNER_ACCOUNT, // 3
87 Calendar.CTAG // 4
88 };*/
90 /* // The indices for the projection array above.
91 private static final int PROJECTION_ID_INDEX = 0;
92 private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
93 private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
94 private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
95 */
97 /*
98 private static final String[] EVENT_PROJECTION = new String[] {
99 Events._ID,
100 Events._SYNC_ID,
101 Events.SYNC_DATA1,
102 Events.CALENDAR_ID
103 };
104 */
106 // ignore same CTag
107 //private static final boolean FORCE_SYNCHRONIZE = false;
108 // drop all calendar before synchro
109 //private static final boolean DROP_CALENDAR_EVENTS = false;
111 public SyncAdapter(Context context, boolean autoInitialize) {
112 super(context, autoInitialize);
113 //android.os.Debug.waitForDebugger();
114 mAccountManager = AccountManager.get(context);
115 try {
116 mVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
117 } catch (NameNotFoundException e) {
118 e.printStackTrace();
119 }
120 // mContext = context;
121 }
123 @Override
124 public void onPerformSync(Account account, Bundle extras, String authority,
125 ContentProviderClient provider, SyncResult syncResult) {
126 boolean bolError = false;
128 String url = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_URL_KEY);
129 this.mCountPerformSync += 1;
130 Log.v(TAG, "onPerformSync() count:" + String.valueOf(this.mCountPerformSync) + " on " + account.name + " with URL " + url);
132 CalendarList serverCalList;
134 CalendarList androidCalList = new CalendarList(account, provider, CalendarSource.Android, url);
135 androidCalList.readCalendarFromClient();
136 ArrayList<Uri> notifyList = new ArrayList<Uri>();
138 try {
139 String Username = "";
140 String UserDataVersion = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_VERSION);
141 if (UserDataVersion == null) {
142 Username = account.name;
143 } else {
144 Username = mAccountManager.getUserData(account, AuthenticatorActivity.USER_DATA_USERNAME);
145 }
147 CaldavFacade facade = new CaldavFacade(Username, mAccountManager.getPassword(account), url);
148 facade.setAccount(account);
149 facade.setProvider(provider);
150 facade.setVersion(mVersion);
151 serverCalList = facade.getCalendarList(this.getContext());
152 //String davProperties = facade.getLastDav();
153 Log.i(TAG, String.valueOf(androidCalList.getCalendarList().size()) + " calendars found at android");
155 for (DavCalendar serverCalendar : serverCalList.getCalendarList()) {
156 Log.i(TAG, "Detected calendar name=" + serverCalendar.getCalendarDisplayName() + " URI=" + serverCalendar.getURI());
158 Uri androidCalendarUri = serverCalendar.checkAndroidCalendarList(androidCalList, this.getContext());
160 // check if the adapter was able to get an existing calendar or create a new one
161 if (androidCalendarUri != null) {
162 // the provider seems to work correct, reset the counter
163 mCountProviderFailed = 0;
164 DavCalendar androidCalendar = androidCalList.getCalendarByAndroidUri(androidCalendarUri);
166 //if ((FORCE_SYNCHRONIZE) || (androidCalendar.getcTag() == null) || (!androidCalendar.getcTag().equals(serverCalendar.getcTag()))) {
167 if ((androidCalendar.getcTag() == null) || (!androidCalendar.getcTag().equals(serverCalendar.getcTag()))) {
168 Log.d(TAG, "CTag has changed, something to synchronise");
169 if (serverCalendar.readCalendarEvents(facade)) {
170 this.synchroniseEvents(androidCalendar, serverCalendar, syncResult.stats, notifyList);
172 Log.d(TAG, "Updating stored CTag");
173 //serverCalendar.updateAndroidCalendar(androidCalendarUri, Calendar.CTAG, serverCalendar.getcTag());
174 androidCalendar.setCTag(serverCalendar.getcTag(), true);
175 } else {
176 Log.d(TAG, "unable to read events from server calendar");
177 }
178 } else {
179 Log.d(TAG, "CTag has not changed, nothing to do");
181 /* this is unnecessary. "SkippedEntries" are:
182 * Counter for tracking how many entries, either from the server or the local store,
183 * were ignored during the sync operation. This could happen if the SyncAdapter detected
184 * some unparsable data but decided to skip it and move on rather than failing immediately.
185 */
187 /*long CalendarID = ContentUris.parseId(androidCalendarUri);
188 String selection = "(" + Events.CALENDAR_ID + " = ?)";
189 String[] selectionArgs = new String[] {String.valueOf(CalendarID)};
190 Cursor countCursor = provider.query(Events.CONTENT_URI, new String[] {"count(*) AS count"},
191 selection,
192 selectionArgs,
193 null);
195 countCursor.moveToFirst();
196 int count = countCursor.getInt(0);
197 syncResult.stats.numSkippedEntries += count;
198 countCursor.close();*/
200 }
202 this.checkDirtyAndroidEvents(provider, account, androidCalendarUri, facade, serverCalendar.getURI(), syncResult.stats, notifyList);
203 } else {
204 // this happens if the data provider failes to get an existing or create a new calendar
205 mCountProviderFailed += 1;
206 Log.e(TAG, "failed to get an existing or create a new calendar");
207 syncResult.stats.numIoExceptions += 1;
208 if (mCountProviderFailed >= mCountProviderFailedMax) {
209 // see issue #96
210 NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (provider failed)", "are you using CyanogenMod in Incognito Mode?");
211 } else {
212 NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (provider failed)", "the provider failed to get an existing or create a new calendar");
213 }
214 bolError = true;
215 }
216 }
218 if (!bolError) {
219 // check whether a calendar is not synced -> delete it at android
220 androidCalList.deleteCalendarOnClientSideOnly(this.getContext());
221 }
223 // notify the ContentResolver
224 for (Uri uri : androidCalList.getNotifyList()) {
225 this.getContext().getContentResolver().notifyChange(uri, null);
226 }
227 for (Uri uri : serverCalList.getNotifyList()) {
228 this.getContext().getContentResolver().notifyChange(uri, null);
229 }
230 for (Uri uri : notifyList) {
231 this.getContext().getContentResolver().notifyChange(uri, null);
232 }
234 //Log.i(TAG,"Statistiks for Calendar: " + serverCalendar.getURI().toString());
235 //Log.i(TAG,"Statistiks for AndroidCalendar: " + androidCalendar.getAndroidCalendarUri().toString());
236 Log.i(TAG,"Entries: " + String.valueOf(syncResult.stats.numEntries));
237 Log.i(TAG,"Rows inserted: " + String.valueOf(syncResult.stats.numInserts));
238 Log.i(TAG,"Rows updated: " + String.valueOf(syncResult.stats.numUpdates));
239 Log.i(TAG,"Rows deleted: " + String.valueOf(syncResult.stats.numDeletes));
240 Log.i(TAG,"Rows skipped: " + String.valueOf(syncResult.stats.numSkippedEntries));
241 Log.i(TAG,"Io Exceptions: " + String.valueOf(syncResult.stats.numIoExceptions));
242 Log.i(TAG,"Parse Exceptions: " + String.valueOf(syncResult.stats.numParseExceptions));
243 Log.i(TAG,"Auth Exceptions: " + String.valueOf(syncResult.stats.numAuthExceptions));
244 Log.i(TAG,"Conflict Detected Exceptions: " + String.valueOf(syncResult.stats.numConflictDetectedExceptions));
246 /*} catch (final AuthenticatorException e) {
247 syncResult.stats.numParseExceptions++;
248 Log.e(TAG, "AuthenticatorException", e);*/
249 /*} catch (final OperationCanceledException e) {
250 Log.e(TAG, "OperationCanceledExcetpion", e);*/
251 } catch (final IOException e) {
252 Log.e(TAG, "IOException", e);
253 syncResult.stats.numIoExceptions++;
254 NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (IO)", e.getMessage());
255 //NotificationsHelper.getCurrentSyncLog().addException(e);
256 /*} catch (final AuthenticationException e) {
257 //mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authtoken);
258 syncResult.stats.numAuthExceptions++;
259 Log.e(TAG, "AuthenticationException", e);*/
260 } catch (final ParseException e) {
261 syncResult.stats.numParseExceptions++;
262 Log.e(TAG, "ParseException", e);
263 NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (parsing)", e.getMessage());
264 //NotificationsHelper.getCurrentSyncLog().addException(e);
265 /*} catch (final JSONException e) {
266 syncResult.stats.numParseExceptions++;
267 Log.e(TAG, "JSONException", e);*/
268 } catch (Exception e) {
269 Log.e(TAG, "Updating calendar exception " + e.getClass().getName(), e);
270 syncResult.stats.numParseExceptions++;
271 NotificationsHelper.signalSyncErrors(this.getContext(), "Caldav sync error (general)", e.getMessage());
272 //NotificationsHelper.getCurrentSyncLog().addException(e);
273 //throw new RuntimeException(e);
274 }
275 }
277 public void onSyncCanceled () {
278 //TODO: implement SyncCanceled
279 this.mCountSyncCanceled += 1;
280 Log.v(TAG, "onSyncCanceled() count:" + String.valueOf(this.mCountSyncCanceled));
281 }
284 /**
285 * both calender event and android event have been found.
286 * server wins always at the moment.
287 * @param androidCalendar
288 * @param serverCalendar
289 * @param stats
290 * @param notifyList
291 * @throws ClientProtocolException
292 * @throws URISyntaxException
293 * @throws IOException
294 * @throws ParserConfigurationException
295 * @throws SAXException
296 * @throws RemoteException
297 * @throws CaldavProtocolException
298 * @throws ParserException
299 * @see SyncAdapter#updateAndroidEvent(ContentProviderClient, Account, AndroidEvent, CalendarEvent)
300 * @see SyncAdapter#tagAndroidEvent(ContentProviderClient, Account, AndroidEvent)
301 * @see SyncAdapter#untagAndroidEvents(ContentProviderClient, Account, Uri)
302 * @see SyncAdapter#deleteUntaggedEvents(ContentProviderClient, Account, Uri)
303 */
304 private void synchroniseEvents(
305 DavCalendar androidCalendar,
306 DavCalendar serverCalendar,
307 SyncStats stats,
308 ArrayList<Uri> notifyList
309 ) throws ClientProtocolException, URISyntaxException, IOException, ParserConfigurationException, SAXException, RemoteException, CaldavProtocolException, ParserException {
311 /*if (DROP_CALENDAR_EVENTS) {
312 dropAllEvents(account, provider, androidCalendar.getAndroidCalendarUri());
313 }*/
315 int rowInsert = 0;
316 int rowUpdate = 0;
317 int rowTag = 0;
318 int rowDelete = 0;
319 int rowUntag = 0;
320 int rowSkip = 0;
322 for (CalendarEvent calendarEvent : serverCalendar.getCalendarEvents()) {
323 try {
324 AndroidEvent androidEvent = calendarEvent.getAndroidEvent(androidCalendar);
326 Log.i(TAG, "Event " + calendarEvent.getUri().toString()+ " androidUri="+androidEvent);
328 if (androidEvent == null) {
329 /* new android event */
330 if (calendarEvent.createAndroidEvent(androidCalendar)) {
331 rowInsert += 1;
332 androidEvent = calendarEvent.getAndroidEvent(androidCalendar);
333 notifyList.add(androidEvent.getUri());
334 } else {
335 rowSkip += 1;
336 }
337 } else {
338 /* the android exists */
339 String androidETag = androidEvent.getETag();
340 if (androidETag == null)
341 androidETag = "";
342 Log.d(TAG, "Event compare: " + androidETag + " <> " + calendarEvent.getETag().toString());
343 if ((androidEvent.getETag() == null) || (!androidETag.equals(calendarEvent.getETag()))) {
344 /* the android event is getting updated */
345 if (calendarEvent.updateAndroidEvent(androidEvent)) {
346 rowUpdate += 1;
347 notifyList.add(androidEvent.getUri());
348 } else {
349 rowSkip += 1;
350 }
351 }
352 }
353 if (androidEvent != null)
354 //if (androidEvent.tagAndroidEvent())
355 if (androidCalendar.tagAndroidEvent(androidEvent))
356 rowTag += 1;
359 } catch (ParserException ex) {
360 Log.e(TAG, "Parser exception", ex);
361 stats.numParseExceptions++;
363 NotificationsHelper.signalSyncErrors(getContext(), "Caldav sync error (parsing)", ex.getMessage());
364 //NotificationsHelper.getCurrentSyncLog().addException(ex);
365 } catch (CaldavProtocolException ex) {
366 Log.e(TAG, "Caldav exception", ex);
367 stats.numParseExceptions++;
369 NotificationsHelper.signalSyncErrors(getContext(), "Caldav sync error (caldav)", ex.getMessage());
370 //NotificationsHelper.getCurrentSyncLog().addException(ex);
371 }
372 }
374 rowDelete = androidCalendar.deleteUntaggedEvents();
375 rowUntag = androidCalendar.untagAndroidEvents();
377 /*Log.i(TAG,"Statistiks for Calendar: " + serverCalendar.getURI().toString());
378 Log.i(TAG,"Statistiks for AndroidCalendar: " + androidCalendar.getAndroidCalendarUri().toString());
379 Log.i(TAG,"Rows inserted: " + String.valueOf(rowInsert));
380 Log.i(TAG,"Rows updated: " + String.valueOf(rowUpdate));
381 Log.i(TAG,"Rows deleted: " + String.valueOf(rowDelete));
382 Log.i(TAG,"Rows skipped: " + String.valueOf(rowSkip));*/
383 Log.i(TAG,"Rows tagged: " + String.valueOf(rowTag));
384 Log.i(TAG,"Rows untagged: " + String.valueOf(rowUntag));
386 stats.numInserts += rowInsert;
387 stats.numUpdates += rowUpdate;
388 stats.numDeletes += rowDelete;
389 stats.numSkippedEntries += rowSkip;
390 stats.numEntries += rowInsert + rowUpdate + rowDelete;
392 }
394 /**
395 * checks the android events for the dirty flag.
396 * the flag is set by android when the event has been changed.
397 * the dirty flag is removed when an android event has been updated from calendar event
398 * @param provider
399 * @param account
400 * @param calendarUri
401 * @param facade
402 * @param caldavCalendarUri
403 * @param stats
404 * @param notifyList
405 * @return count of dirty events
406 */
407 private int checkDirtyAndroidEvents(
408 ContentProviderClient provider,
409 Account account,
410 Uri calendarUri,
411 CaldavFacade facade,
412 URI caldavCalendarUri,
413 SyncStats stats,
414 ArrayList<Uri> notifyList
415 ) {
416 Cursor curEvent = null;
417 Cursor curAttendee = null;
418 Cursor curReminder = null;
419 Long EventID;
420 Long CalendarID;
421 AndroidEvent androidEvent = null;
422 int rowDirty = 0;
423 int rowInsert = 0;
424 int rowUpdate = 0;
425 int rowDelete = 0;
427 try {
428 CalendarID = ContentUris.parseId(calendarUri);
429 String selection = "(" + Events.DIRTY + " = ?) AND (" + Events.CALENDAR_ID + " = ?)";
430 String[] selectionArgs = new String[] {"1", CalendarID.toString()};
431 curEvent = provider.query(Events.CONTENT_URI, null, selection, selectionArgs, null);
433 while (curEvent.moveToNext()) {
434 EventID = curEvent.getLong(curEvent.getColumnIndex(Events._ID));
435 Uri returnedUri = ContentUris.withAppendedId(Events.CONTENT_URI, EventID);
437 //androidEvent = new AndroidEvent(account, provider, returnedUri, calendarUri);
438 androidEvent = new AndroidEvent(returnedUri, calendarUri);
439 androidEvent.readContentValues(curEvent);
441 selection = "(" + Attendees.EVENT_ID + " = ?)";
442 selectionArgs = new String[] {String.valueOf(EventID)};
443 curAttendee = provider.query(Attendees.CONTENT_URI, null, selection, selectionArgs, null);
444 selection = "(" + Reminders.EVENT_ID + " = ?)";
445 selectionArgs = new String[] {String.valueOf(EventID)};
446 curReminder = provider.query(Reminders.CONTENT_URI, null, selection, selectionArgs, null);
447 androidEvent.readAttendees(curAttendee);
448 androidEvent.readReminder(curReminder);
449 curAttendee.close();
450 curReminder.close();
452 String SyncID = androidEvent.ContentValues.getAsString(Events._SYNC_ID);
454 boolean Deleted = false;
455 int intDeleted = 0;
456 intDeleted = curEvent.getInt(curEvent.getColumnIndex(Events.DELETED));
457 Deleted = (intDeleted == 1);
459 if (SyncID == null) {
460 // new Android event
461 String newGUID = java.util.UUID.randomUUID().toString() + "-caldavsyncadapter";
462 String calendarPath = caldavCalendarUri.getPath();
463 if (!calendarPath.endsWith("/"))
464 calendarPath += "/";
466 SyncID = calendarPath + newGUID + ".ics";
468 androidEvent.createIcs(newGUID);
470 if (facade.createEvent(URI.create(SyncID), androidEvent.getIcsEvent().toString())) {
471 //HINT: bugfix for google calendar replace("@", "%40")
472 if (SyncID.contains("@"))
473 SyncID = SyncID.replace("@", "%40");
474 ContentValues values = new ContentValues();
475 values.put(Events._SYNC_ID, SyncID);
477 //google doesn't send the etag after creation
478 //HINT: my SabreDAV send always the same etag after putting a new event
479 //String LastETag = facade.getLastETag();
480 //if (!LastETag.equals("")) {
481 // values.put(Event.ETAG, LastETag);
482 //} else {
483 //so get the etag with a new REPORT
484 CalendarEvent calendarEvent = new CalendarEvent(account, provider);
485 calendarEvent.calendarURL = caldavCalendarUri.toURL();
486 URI SyncURI = new URI(SyncID);
487 calendarEvent.setUri(SyncURI);
488 CaldavFacade.getEvent(calendarEvent);
489 values.put(Event.ETAG, calendarEvent.getETag());
490 //}
491 values.put(Event.UID, newGUID);
492 values.put(Events.DIRTY, 0);
493 values.put(Event.RAWDATA, androidEvent.getIcsEvent().toString());
495 int rowCount = provider.update(asSyncAdapter(androidEvent.getUri(), account.name, account.type), values, null, null);
496 if (rowCount == 1) {
497 rowInsert += 1;
498 notifyList.add(androidEvent.getUri());
499 }
500 }
501 } else if (Deleted) {
502 // deleted Android event
503 if (facade.deleteEvent(URI.create(SyncID), androidEvent.getETag())) {
504 String mSelectionClause = "(" + Events._ID + "= ?)";
505 String[] mSelectionArgs = {String.valueOf(EventID)};
507 int countDeleted = provider.delete(asSyncAdapter(Events.CONTENT_URI, account.name, account.type), mSelectionClause, mSelectionArgs);
509 if (countDeleted == 1) {
510 rowDelete += 1;
511 notifyList.add(androidEvent.getUri());
512 }
513 }
514 } else {
515 //update the android event to the server
516 String uid = androidEvent.getUID();
517 if ((uid == null) || (uid.equals(""))) {
518 //COMPAT: this is needed because in the past, the UID was not stored in the android event
519 CalendarEvent calendarEvent = new CalendarEvent(account, provider);
520 URI syncURI = new URI(SyncID);
521 calendarEvent.setUri(syncURI);
522 calendarEvent.calendarURL = caldavCalendarUri.toURL();
523 if (calendarEvent.fetchBody()) {
524 calendarEvent.readContentValues();
525 uid = calendarEvent.getUID();
526 }
527 }
528 if (uid != null) {
529 androidEvent.createIcs(uid);
531 if (facade.updateEvent(URI.create(SyncID), androidEvent.getIcsEvent().toString(), androidEvent.getETag())) {
532 selection = "(" + Events._ID + "= ?)";
533 selectionArgs = new String[] {EventID.toString()};
534 androidEvent.ContentValues.put(Events.DIRTY, 0);
536 //google doesn't send the etag after update
537 String LastETag = facade.getLastETag();
538 if (!LastETag.equals("")) {
539 androidEvent.ContentValues.put(Event.ETAG, LastETag);
540 } else {
541 //so get the etag with a new REPORT
542 CalendarEvent calendarEvent = new CalendarEvent(account, provider);
543 calendarEvent.calendarURL = caldavCalendarUri.toURL();
544 URI SyncURI = new URI(SyncID);
545 calendarEvent.setUri(SyncURI);
546 CaldavFacade.getEvent(calendarEvent);
547 androidEvent.ContentValues.put(Event.ETAG, calendarEvent.getETag());
548 }
549 androidEvent.ContentValues.put(Event.RAWDATA, androidEvent.getIcsEvent().toString());
550 int RowCount = provider.update(asSyncAdapter(androidEvent.getUri(), account.name, account.type), androidEvent.ContentValues, null, null);
552 if (RowCount == 1) {
553 rowUpdate += 1;
554 notifyList.add(androidEvent.getUri());
555 }
556 } else {
557 rowDirty += 1;
558 }
559 } else {
560 rowDirty += 1;
561 }
562 }
563 }
564 curEvent.close();
566 /*if ((rowInsert > 0) || (rowUpdate > 0) || (rowDelete > 0) || (rowDirty > 0)) {
567 Log.i(TAG,"Android Rows inserted: " + String.valueOf(rowInsert));
568 Log.i(TAG,"Android Rows updated: " + String.valueOf(rowUpdate));
569 Log.i(TAG,"Android Rows deleted: " + String.valueOf(rowDelete));
570 Log.i(TAG,"Android Rows dirty: " + String.valueOf(rowDirty));
571 }*/
573 stats.numInserts += rowInsert;
574 stats.numUpdates += rowUpdate;
575 stats.numDeletes += rowDelete;
576 stats.numSkippedEntries += rowDirty;
577 stats.numEntries += rowInsert + rowUpdate + rowDelete;
578 } catch (RemoteException e) {
579 e.printStackTrace();
580 } catch (URISyntaxException e) {
581 // TODO Automatisch generierter Erfassungsblock
582 e.printStackTrace();
583 } catch (ClientProtocolException e) {
584 // TODO Automatisch generierter Erfassungsblock
585 e.printStackTrace();
586 } catch (IOException e) {
587 // TODO Automatisch generierter Erfassungsblock
588 e.printStackTrace();
589 } catch (CaldavProtocolException e) {
590 // TODO Automatisch generierter Erfassungsblock
591 e.printStackTrace();
592 } catch (ParserException e) {
593 // TODO Automatisch generierter Erfassungsblock
594 e.printStackTrace();
595 }
597 return rowDirty;
598 }
600 /* private Account UpgradeAccount(Account OldAccount) {
601 String Username = OldAccount.name;
602 String Type = OldAccount.type;
603 String Password = this.mAccountManager.getPassword(OldAccount);
604 String Url = this.mAccountManager.getUserData(OldAccount, AuthenticatorActivity.USER_DATA_URL_KEY);
606 Account NewAccount = new Account(Username + AuthenticatorActivity.ACCOUNT_NAME_SPLITTER + Url, Type);
607 if (this.mAccountManager.addAccountExplicitly(NewAccount, Password, null)) {
608 this.mAccountManager.setUserData(NewAccount, AuthenticatorActivity.USER_DATA_URL_KEY, Url);
609 this.mAccountManager.setUserData(NewAccount, AuthenticatorActivity.USER_DATA_USERNAME, Username);
610 }
611 this.mAccountManager.removeAccount(OldAccount, null, null);
613 return NewAccount;
614 }*/
616 /* private void dropAllEvents(Account account, ContentProviderClient provider, Uri calendarUri) throws RemoteException {
618 Log.i(TAG, "Deleting all calendar events for "+calendarUri);
620 String selection = "(" + Events.CALENDAR_ID + " = ?)";
621 String[] selectionArgs = new String[] {Long.toString(ContentUris.parseId(calendarUri))};
623 provider.delete(asSyncAdapter(Events.CONTENT_URI, account.name, account.type),
624 selection, selectionArgs);
626 }*/
628 private static Uri asSyncAdapter(Uri uri, String account, String accountType) {
629 return uri.buildUpon()
630 .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
631 .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
632 .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
633 }
635 }