2015-03-08 22:30:03 +00:00
|
|
|
|
/*
|
2015-05-27 08:48:27 +00:00
|
|
|
|
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
2014-12-20 19:21:46 +00:00
|
|
|
|
* 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
|
2015-03-08 22:30:03 +00:00
|
|
|
|
*/
|
2016-02-24 14:56:30 +00:00
|
|
|
|
package at.bitfire.davdroid;
|
2014-12-20 19:21:46 +00:00
|
|
|
|
|
|
|
|
|
import android.accounts.Account;
|
|
|
|
|
import android.accounts.AccountManager;
|
2015-10-15 13:36:55 +00:00
|
|
|
|
import android.app.Notification;
|
|
|
|
|
import android.app.NotificationManager;
|
|
|
|
|
import android.content.ContentProviderClient;
|
2014-12-20 19:21:46 +00:00
|
|
|
|
import android.content.ContentResolver;
|
|
|
|
|
import android.content.ContentUris;
|
|
|
|
|
import android.content.ContentValues;
|
|
|
|
|
import android.content.Context;
|
2016-03-20 16:41:05 +00:00
|
|
|
|
import android.content.Intent;
|
2015-03-08 22:30:03 +00:00
|
|
|
|
import android.content.PeriodicSync;
|
2014-12-20 19:21:46 +00:00
|
|
|
|
import android.database.Cursor;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import android.database.sqlite.SQLiteDatabase;
|
2016-03-20 16:41:05 +00:00
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
2014-12-20 19:21:46 +00:00
|
|
|
|
import android.net.Uri;
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.provider.CalendarContract;
|
|
|
|
|
import android.provider.CalendarContract.Calendars;
|
2015-10-15 13:36:55 +00:00
|
|
|
|
import android.provider.ContactsContract;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
|
import android.support.v7.app.NotificationCompat;
|
2015-10-15 13:36:55 +00:00
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import java.lang.reflect.Method;
|
2014-12-21 01:19:06 +00:00
|
|
|
|
import java.net.URI;
|
|
|
|
|
import java.net.URISyntaxException;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import java.util.HashSet;
|
2015-03-08 22:30:03 +00:00
|
|
|
|
import java.util.List;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import java.util.Set;
|
2016-02-24 22:08:19 +00:00
|
|
|
|
import java.util.logging.Level;
|
2014-12-21 01:19:06 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import at.bitfire.davdroid.model.ServiceDB;
|
2016-03-25 14:18:31 +00:00
|
|
|
|
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
|
|
|
|
import at.bitfire.davdroid.model.ServiceDB.HomeSets;
|
|
|
|
|
import at.bitfire.davdroid.model.ServiceDB.Services;
|
2015-10-15 13:36:55 +00:00
|
|
|
|
import at.bitfire.davdroid.resource.LocalAddressBook;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import at.bitfire.davdroid.resource.LocalCalendar;
|
|
|
|
|
import at.bitfire.davdroid.resource.LocalTaskList;
|
|
|
|
|
import at.bitfire.ical4android.CalendarStorageException;
|
|
|
|
|
import at.bitfire.ical4android.TaskProvider;
|
2015-10-15 13:36:55 +00:00
|
|
|
|
import at.bitfire.vcard4android.ContactsStorageException;
|
2014-12-21 01:19:06 +00:00
|
|
|
|
import lombok.Cleanup;
|
2016-03-19 21:17:56 +00:00
|
|
|
|
import okhttp3.HttpUrl;
|
2014-12-20 19:21:46 +00:00
|
|
|
|
|
|
|
|
|
public class AccountSettings {
|
2016-03-25 14:18:31 +00:00
|
|
|
|
private final static int CURRENT_VERSION = 3;
|
|
|
|
|
private final static String
|
|
|
|
|
KEY_SETTINGS_VERSION = "version",
|
2015-10-15 13:36:55 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
KEY_USERNAME = "user_name",
|
2016-03-25 14:18:31 +00:00
|
|
|
|
KEY_AUTH_PREEMPTIVE = "auth_preemptive";
|
2015-03-08 22:30:03 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
/** Time range limitation to the past [in days]
|
2016-03-16 17:23:52 +00:00
|
|
|
|
value = null default value (DEFAULT_TIME_RANGE_PAST_DAYS)
|
|
|
|
|
< 0 (-1) no limit
|
|
|
|
|
>= 0 entries more than n days in the past won't be synchronized
|
|
|
|
|
*/
|
|
|
|
|
private final static String KEY_TIME_RANGE_PAST_DAYS = "time_range_past_days";
|
|
|
|
|
private final static int DEFAULT_TIME_RANGE_PAST_DAYS = 90;
|
|
|
|
|
|
2016-03-25 14:18:31 +00:00
|
|
|
|
public final static long SYNC_INTERVAL_MANUALLY = -1;
|
|
|
|
|
|
|
|
|
|
final Context context;
|
|
|
|
|
final AccountManager accountManager;
|
|
|
|
|
final Account account;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AccountSettings(@NonNull Context context, @NonNull Account account) throws InvalidAccountException {
|
|
|
|
|
this.context = context;
|
|
|
|
|
this.account = account;
|
|
|
|
|
|
|
|
|
|
accountManager = AccountManager.get(context);
|
|
|
|
|
|
|
|
|
|
synchronized(AccountSettings.class) {
|
|
|
|
|
String versionStr = accountManager.getUserData(account, KEY_SETTINGS_VERSION);
|
|
|
|
|
if (versionStr == null)
|
|
|
|
|
throw new InvalidAccountException(account);
|
|
|
|
|
|
|
|
|
|
int version = 0;
|
|
|
|
|
try {
|
|
|
|
|
version = Integer.parseInt(versionStr);
|
|
|
|
|
} catch (NumberFormatException ignored) {
|
|
|
|
|
}
|
2016-03-19 21:17:56 +00:00
|
|
|
|
App.log.info("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION);
|
2015-10-15 13:36:55 +00:00
|
|
|
|
|
2016-03-25 14:18:31 +00:00
|
|
|
|
if (version < CURRENT_VERSION) {
|
2016-03-19 21:17:56 +00:00
|
|
|
|
Notification notify = new NotificationCompat.Builder(context)
|
2016-03-20 16:41:05 +00:00
|
|
|
|
.setSmallIcon(R.drawable.ic_new_releases_light)
|
|
|
|
|
.setLargeIcon(((BitmapDrawable)context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
2016-03-19 21:17:56 +00:00
|
|
|
|
.setContentTitle(context.getString(R.string.settings_version_update))
|
2016-03-20 16:41:05 +00:00
|
|
|
|
.setContentText(context.getString(R.string.settings_version_update_settings_updated))
|
|
|
|
|
.setSubText(context.getString(R.string.settings_version_update_install_hint))
|
2016-03-24 19:51:09 +00:00
|
|
|
|
.setStyle(new NotificationCompat.BigTextStyle()
|
|
|
|
|
.bigText(context.getString(R.string.settings_version_update_settings_updated)))
|
2016-03-19 21:17:56 +00:00
|
|
|
|
.setCategory(NotificationCompat.CATEGORY_SYSTEM)
|
|
|
|
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
|
|
|
.setLocalOnly(true)
|
|
|
|
|
.build();
|
|
|
|
|
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
|
nm.notify(Constants.NOTIFICATION_ACCOUNT_SETTINGS_UPDATED, notify);
|
2015-10-15 13:36:55 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
update(version);
|
2015-10-15 13:36:55 +00:00
|
|
|
|
}
|
2016-03-25 14:18:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Bundle initialUserData(String userName, boolean preemptive) {
|
|
|
|
|
Bundle bundle = new Bundle();
|
|
|
|
|
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
|
|
|
|
|
bundle.putString(KEY_USERNAME, userName);
|
|
|
|
|
bundle.putString(KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive));
|
|
|
|
|
return bundle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// authentication settings
|
|
|
|
|
|
|
|
|
|
public String username() { return accountManager.getUserData(account, KEY_USERNAME); }
|
|
|
|
|
public void username(@NonNull String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
|
|
|
|
|
|
|
|
|
|
public String password() { return accountManager.getPassword(account); }
|
|
|
|
|
public void password(@NonNull String password) { accountManager.setPassword(account, password); }
|
|
|
|
|
|
|
|
|
|
public boolean preemptiveAuth() { return Boolean.parseBoolean(accountManager.getUserData(account, KEY_AUTH_PREEMPTIVE)); }
|
|
|
|
|
public void preemptiveAuth(boolean preemptive) { accountManager.setUserData(account, KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive)); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// sync. settings
|
|
|
|
|
|
|
|
|
|
public Long getSyncInterval(@NonNull String authority) {
|
|
|
|
|
if (ContentResolver.getIsSyncable(account, authority) <= 0)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
if (ContentResolver.getSyncAutomatically(account, authority)) {
|
|
|
|
|
List<PeriodicSync> syncs = ContentResolver.getPeriodicSyncs(account, authority);
|
|
|
|
|
if (syncs.isEmpty())
|
|
|
|
|
return SYNC_INTERVAL_MANUALLY;
|
|
|
|
|
else
|
|
|
|
|
return syncs.get(0).period;
|
|
|
|
|
} else
|
|
|
|
|
return SYNC_INTERVAL_MANUALLY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setSyncInterval(@NonNull String authority, long seconds) {
|
|
|
|
|
if (seconds == SYNC_INTERVAL_MANUALLY) {
|
|
|
|
|
ContentResolver.setSyncAutomatically(account, authority, false);
|
|
|
|
|
} else {
|
|
|
|
|
ContentResolver.setSyncAutomatically(account, authority, true);
|
|
|
|
|
ContentResolver.addPeriodicSync(account, authority, new Bundle(), seconds);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-08 22:30:03 +00:00
|
|
|
|
|
2016-03-16 17:23:52 +00:00
|
|
|
|
public Integer getTimeRangePastDays() {
|
|
|
|
|
String strDays = accountManager.getUserData(account, KEY_TIME_RANGE_PAST_DAYS);
|
|
|
|
|
if (strDays != null) {
|
|
|
|
|
int days = Integer.valueOf(strDays);
|
|
|
|
|
return days < 0 ? null : days;
|
|
|
|
|
} else
|
|
|
|
|
return DEFAULT_TIME_RANGE_PAST_DAYS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setTimeRangePastDays(Integer days) {
|
|
|
|
|
accountManager.setUserData(account, KEY_TIME_RANGE_PAST_DAYS, String.valueOf(days == null ? -1 : days));
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-25 14:18:31 +00:00
|
|
|
|
|
|
|
|
|
// update from previous account settings
|
|
|
|
|
|
|
|
|
|
private void update(int fromVersion) {
|
|
|
|
|
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++) {
|
2016-03-19 21:17:56 +00:00
|
|
|
|
App.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion);
|
|
|
|
|
try {
|
|
|
|
|
Method updateProc = getClass().getDeclaredMethod("update_" + fromVersion + "_" + toVersion);
|
|
|
|
|
updateProc.invoke(this);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
App.log.log(Level.SEVERE, "Couldn't update account settings", e);
|
2015-10-15 13:36:55 +00:00
|
|
|
|
}
|
2016-03-19 21:17:56 +00:00
|
|
|
|
fromVersion = toVersion;
|
|
|
|
|
}
|
2016-03-25 14:18:31 +00:00
|
|
|
|
}
|
2015-10-15 13:36:55 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
@SuppressWarnings({ "Recycle", "unused" })
|
2015-10-15 13:36:55 +00:00
|
|
|
|
private void update_1_2() throws ContactsStorageException {
|
2015-10-18 14:20:26 +00:00
|
|
|
|
/* - KEY_ADDRESSBOOK_URL ("addressbook_url"),
|
2015-10-15 13:36:55 +00:00
|
|
|
|
- KEY_ADDRESSBOOK_CTAG ("addressbook_ctag"),
|
|
|
|
|
- KEY_ADDRESSBOOK_VCARD_VERSION ("addressbook_vcard_version") are not used anymore (now stored in ContactsContract.SyncState)
|
|
|
|
|
- KEY_LAST_ANDROID_VERSION ("last_android_version") has been added
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// move previous address book info to ContactsContract.SyncState
|
|
|
|
|
@Cleanup("release") ContentProviderClient provider = context.getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
|
2015-10-18 14:20:26 +00:00
|
|
|
|
if (provider == null)
|
|
|
|
|
throw new ContactsStorageException("Couldn't access Contacts provider");
|
|
|
|
|
|
|
|
|
|
LocalAddressBook addr = new LocalAddressBook(account, provider);
|
|
|
|
|
|
|
|
|
|
// until now, ContactsContract.Settings.UNGROUPED_VISIBLE was not set explicitly
|
|
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
|
values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1);
|
|
|
|
|
addr.updateSettings(values);
|
|
|
|
|
|
|
|
|
|
String url = accountManager.getUserData(account, "addressbook_url");
|
|
|
|
|
if (!TextUtils.isEmpty(url))
|
|
|
|
|
addr.setURL(url);
|
|
|
|
|
accountManager.setUserData(account, "addressbook_url", null);
|
|
|
|
|
|
|
|
|
|
String cTag = accountManager.getUserData(account, "addressbook_ctag");
|
|
|
|
|
if (!TextUtils.isEmpty(cTag))
|
|
|
|
|
addr.setCTag(cTag);
|
|
|
|
|
accountManager.setUserData(account, "addressbook_ctag", null);
|
2015-10-15 13:36:55 +00:00
|
|
|
|
|
|
|
|
|
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "2");
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
@SuppressWarnings({ "Recycle", "unused" })
|
|
|
|
|
private void update_2_3() {
|
|
|
|
|
// Don't show a warning for Android updates anymore
|
|
|
|
|
accountManager.setUserData(account, "last_android_version", null);
|
|
|
|
|
|
2016-03-20 16:41:05 +00:00
|
|
|
|
Long serviceCardDAV = null, serviceCalDAV = null;
|
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(context);
|
|
|
|
|
try {
|
|
|
|
|
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
|
|
|
// we have to create the WebDAV Service database only from the old address book, calendar and task list URLs
|
|
|
|
|
|
|
|
|
|
// CardDAV: migrate address books
|
|
|
|
|
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
|
|
|
|
|
if (client != null)
|
|
|
|
|
try {
|
|
|
|
|
LocalAddressBook addrBook = new LocalAddressBook(account, client);
|
|
|
|
|
String url = addrBook.getURL();
|
|
|
|
|
if (url != null) {
|
|
|
|
|
App.log.fine("Migrating address book " + url);
|
|
|
|
|
|
|
|
|
|
// insert CardDAV service
|
|
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
|
values.put(Services.ACCOUNT_NAME, account.name);
|
|
|
|
|
values.put(Services.SERVICE, Services.SERVICE_CARDDAV);
|
2016-03-20 16:41:05 +00:00
|
|
|
|
serviceCardDAV = db.insert(Services._TABLE, null, values);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
|
|
|
|
|
// insert address book
|
|
|
|
|
values.clear();
|
2016-03-20 16:41:05 +00:00
|
|
|
|
values.put(Collections.SERVICE_ID, serviceCardDAV);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
values.put(Collections.URL, url);
|
|
|
|
|
values.put(Collections.SYNC, 1);
|
|
|
|
|
db.insert(Collections._TABLE, null, values);
|
|
|
|
|
|
|
|
|
|
// insert home set
|
|
|
|
|
HttpUrl homeSet = HttpUrl.parse(url).resolve("../");
|
|
|
|
|
values.clear();
|
2016-03-20 16:41:05 +00:00
|
|
|
|
values.put(HomeSets.SERVICE_ID, serviceCardDAV);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
values.put(HomeSets.URL, homeSet.toString());
|
|
|
|
|
db.insert(HomeSets._TABLE, null, values);
|
|
|
|
|
}
|
2016-03-20 16:41:05 +00:00
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
} catch (ContactsStorageException e) {
|
|
|
|
|
App.log.log(Level.SEVERE, "Couldn't migrate address book", e);
|
|
|
|
|
} finally {
|
|
|
|
|
client.release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CalDAV: migrate calendars + task lists
|
|
|
|
|
Set<String> collections = new HashSet<>();
|
|
|
|
|
Set<HttpUrl> homeSets = new HashSet<>();
|
|
|
|
|
|
|
|
|
|
client = context.getContentResolver().acquireContentProviderClient(CalendarContract.AUTHORITY);
|
|
|
|
|
if (client != null)
|
|
|
|
|
try {
|
|
|
|
|
LocalCalendar calendars[] = (LocalCalendar[])LocalCalendar.find(account, client, LocalCalendar.Factory.INSTANCE, null, null);
|
|
|
|
|
for (LocalCalendar calendar : calendars) {
|
|
|
|
|
String url = calendar.getName();
|
|
|
|
|
App.log.fine("Migrating calendar " + url);
|
|
|
|
|
collections.add(url);
|
|
|
|
|
homeSets.add(HttpUrl.parse(url).resolve("../"));
|
|
|
|
|
}
|
|
|
|
|
} catch (CalendarStorageException e) {
|
|
|
|
|
App.log.log(Level.SEVERE, "Couldn't migrate calendars", e);
|
|
|
|
|
} finally {
|
|
|
|
|
client.release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskProvider provider = LocalTaskList.acquireTaskProvider(context.getContentResolver());
|
|
|
|
|
if (provider != null)
|
|
|
|
|
try {
|
|
|
|
|
LocalTaskList[] taskLists = (LocalTaskList[])LocalTaskList.find(account, provider, LocalTaskList.Factory.INSTANCE, null, null);
|
|
|
|
|
for (LocalTaskList taskList : taskLists) {
|
|
|
|
|
String url = taskList.getSyncId();
|
|
|
|
|
App.log.fine("Migrating task list " + url);
|
|
|
|
|
collections.add(url);
|
|
|
|
|
homeSets.add(HttpUrl.parse(url).resolve("../"));
|
|
|
|
|
}
|
|
|
|
|
} catch (CalendarStorageException e) {
|
|
|
|
|
App.log.log(Level.SEVERE, "Couldn't migrate task lists", e);
|
|
|
|
|
} finally {
|
|
|
|
|
provider.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!collections.isEmpty()) {
|
|
|
|
|
// insert CalDAV service
|
|
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
|
values.put(Services.ACCOUNT_NAME, account.name);
|
|
|
|
|
values.put(Services.SERVICE, Services.SERVICE_CALDAV);
|
2016-03-20 16:41:05 +00:00
|
|
|
|
serviceCalDAV = db.insert(Services._TABLE, null, values);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
|
|
|
|
|
// insert collections
|
|
|
|
|
for (String url : collections) {
|
|
|
|
|
values.clear();
|
2016-03-20 16:41:05 +00:00
|
|
|
|
values.put(Collections.SERVICE_ID, serviceCalDAV);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
values.put(Collections.URL, url);
|
|
|
|
|
values.put(Collections.SYNC, 1);
|
|
|
|
|
db.insert(Collections._TABLE, null, values);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insert home sets
|
|
|
|
|
for (HttpUrl homeSet : homeSets) {
|
|
|
|
|
values.clear();
|
2016-03-20 16:41:05 +00:00
|
|
|
|
values.put(HomeSets.SERVICE_ID, serviceCalDAV);
|
2016-03-19 21:17:56 +00:00
|
|
|
|
values.put(HomeSets.URL, homeSet.toString());
|
|
|
|
|
db.insert(HomeSets._TABLE, null, values);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
dbHelper.close();
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-20 16:41:05 +00:00
|
|
|
|
// initiate service detection (refresh) to get display names, colors etc.
|
|
|
|
|
Intent refresh = new Intent(context, DavService.class);
|
|
|
|
|
refresh.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
|
|
|
|
if (serviceCardDAV != null) {
|
|
|
|
|
refresh.putExtra(DavService.EXTRA_DAV_SERVICE_ID, serviceCardDAV);
|
|
|
|
|
context.startService(refresh);
|
|
|
|
|
}
|
|
|
|
|
if (serviceCalDAV != null) {
|
|
|
|
|
refresh.putExtra(DavService.EXTRA_DAV_SERVICE_ID, serviceCalDAV);
|
|
|
|
|
context.startService(refresh);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-19 21:17:56 +00:00
|
|
|
|
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "3");
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 19:21:46 +00:00
|
|
|
|
}
|