Improve error/account settings notifications

* move address book settings from account user data to ContactsContract.SyncState
* remove "VCard4 capable?" setting (as it's detected at every sync)
* show user notification when updating settings version or when Android version was increased
* improve stack trace in DebugInfoActivity
* get rid of Guava (use Commons again)
pull/2/head
Ricki Hirner 9 years ago
parent 20bc5af4a3
commit e34abf291e
No known key found for this signature in database
GPG Key ID: C4A212CF0B2B4566

@ -17,8 +17,8 @@ android {
minSdkVersion 14
targetSdkVersion 23
versionCode 75
versionName "0.9-alpha3"
versionCode 76
versionName "0.9-alpha4"
buildConfigField "java.util.Date", "buildTime", "new java.util.Date()"
}
@ -49,8 +49,8 @@ configurations.all {
}
dependencies {
compile 'com.google.guava:guava:18.0'
compile 'dnsjava:dnsjava:2.1.7'
compile 'org.apache.commons:commons-lang3:3.4'
provided 'org.projectlombok:lombok:1.16.6'
compile('org.slf4j:slf4j-android:1.7.12')

@ -14,8 +14,16 @@ public class Constants {
public static final String
ACCOUNT_TYPE = "bitfire.at.davdroid",
WEB_URL_MAIN = "https://davdroid.bitfire.at/?pk_campaign=davdroid-app",
WEB_URL_HELP = "https://davdroid.bitfire.at/configuration?pk_campaign=davdroid-app",
WEB_URL_VIEW_LOGS = "https://github.com/bitfireAT/davdroid/wiki/How-to-view-the-logs";
WEB_URL_HELP = "https://davdroid.bitfire.at/configuration?pk_campaign=davdroid-app";
public static final Logger log = LoggerFactory.getLogger("davdroid");
// notification IDs
public final static int
NOTIFICATION_ANDROID_VERSION_UPDATED = 0,
NOTIFICATION_ACCOUNT_SETTINGS_UPDATED = 1,
NOTIFICATION_CONTACTS_SYNC = 10,
NOTIFICATION_CALENDAR_SYNC = 11,
NOTIFICATION_TASK_SYNC = 12;
}

@ -26,7 +26,9 @@ import lombok.Synchronized;
public class LocalAddressBook extends AndroidAddressBook implements LocalCollection {
protected static final String SYNC_STATE_CTAG = "ctag";
protected static final String
SYNC_STATE_CTAG = "ctag",
SYNC_STATE_URL = "url";
private Bundle syncState = new Bundle();
@ -80,6 +82,27 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
syncState.clear();
}
protected void writeSyncState() throws ContactsStorageException {
@Cleanup("recycle") Parcel parcel = Parcel.obtain();
parcel.writeBundle(syncState);
setSyncState(parcel.marshall());
}
public String getURL() throws ContactsStorageException {
synchronized (syncState) {
readSyncState();
return syncState.getString(SYNC_STATE_URL);
}
}
public void setURL(String url) throws ContactsStorageException {
synchronized (syncState) {
readSyncState();
syncState.putString(SYNC_STATE_URL, url);
writeSyncState();
}
}
@Override
public String getCTag() throws ContactsStorageException {
synchronized (syncState) {
@ -93,11 +116,7 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
synchronized (syncState) {
readSyncState();
syncState.putString(SYNC_STATE_CTAG, cTag);
// write sync state bundle
@Cleanup("recycle") Parcel parcel = Parcel.obtain();
parcel.writeBundle(syncState);
setSyncState(parcel.marshall());
writeSyncState();
}
}

@ -24,11 +24,10 @@ import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.text.TextUtils;
import com.google.common.base.Joiner;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.model.component.VTimeZone;
import org.apache.commons.lang3.StringUtils;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
@ -96,8 +95,8 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
}
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT);
if (Build.VERSION.SDK_INT >= 15) {
values.put(Calendars.ALLOWED_AVAILABILITY, Joiner.on(",").join(Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY));
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, Joiner.on(",").join(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE));
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 }, ", "));
}
return create(account, provider, values);
}

@ -9,6 +9,9 @@ package at.bitfire.davdroid.syncadapter;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@ -16,32 +19,34 @@ import android.content.Context;
import android.content.PeriodicSync;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Calendars;
import android.util.Log;
import android.provider.ContactsContract;
import android.text.TextUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.resource.LocalAddressBook;
import at.bitfire.davdroid.resource.ServerInfo;
import ezvcard.VCardVersion;
import at.bitfire.vcard4android.ContactsStorageException;
import lombok.Cleanup;
public class AccountSettings {
private final static String TAG = "davdroid.AccountSettings";
private final static int CURRENT_VERSION = 1;
private final static int CURRENT_VERSION = 2;
private final static String
KEY_SETTINGS_VERSION = "version",
KEY_USERNAME = "user_name",
KEY_AUTH_PREEMPTIVE = "auth_preemptive",
KEY_ADDRESSBOOK_URL = "addressbook_url",
KEY_ADDRESSBOOK_CTAG = "addressbook_ctag",
KEY_ADDRESSBOOK_VCARD_VERSION = "addressbook_vcard_version";
KEY_LAST_ANDROID_VERSION = "last_android_version";
public final static long SYNC_INTERVAL_MANUALLY = -1;
@ -50,7 +55,7 @@ public class AccountSettings {
final Account account;
public AccountSettings(Context context, Account account) {
public AccountSettings(Context context, Account account) {
this.context = context;
this.account = account;
@ -62,10 +67,43 @@ public class AccountSettings {
version = Integer.parseInt(accountManager.getUserData(account, KEY_SETTINGS_VERSION));
} catch(NumberFormatException e) {
}
if (version < CURRENT_VERSION)
update(version);
Constants.log.info("AccountSettings version: v" + version + ", should be: " + version);
if (version < CURRENT_VERSION) {
showNotification(Constants.NOTIFICATION_ACCOUNT_SETTINGS_UPDATED,
context.getString(R.string.settings_version_update_title),
context.getString(R.string.settings_version_update_description));
update(version);
}
// check whether Android version has changed
int lastAndroidVersion = NumberUtils.toInt(accountManager.getUserData(account, KEY_LAST_ANDROID_VERSION));
if (lastAndroidVersion < Build.VERSION.SDK_INT) {
// notify user
showNotification(Constants.NOTIFICATION_ANDROID_VERSION_UPDATED,
context.getString(R.string.settings_android_update_title),
context.getString(R.string.settings_android_update_description));
accountManager.setUserData(account, KEY_LAST_ANDROID_VERSION, String.valueOf(Build.VERSION.SDK_INT));
}
}
}
protected void showNotification(int id, String title, String message) {
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder n = new Notification.Builder(context);
if (Build.VERSION.SDK_INT >= 16) {
n.setPriority(Notification.PRIORITY_HIGH);
n.setStyle(new Notification.BigTextStyle().bigText(message));
} if (Build.VERSION.SDK_INT >= 20)
n.setLocalOnly(true);
if (Build.VERSION.SDK_INT >= 21)
n.setCategory(Notification.CATEGORY_SYSTEM);
n.setSmallIcon(R.drawable.ic_launcher);
n.setContentTitle(title);
n.setContentText(message);
nm.notify(id, Build.VERSION.SDK_INT >= 16 ? n.build() : n.getNotification());
}
public static Bundle createBundle(ServerInfo serverInfo) {
@ -73,11 +111,6 @@ public class AccountSettings {
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
bundle.putString(KEY_USERNAME, serverInfo.getUserName());
bundle.putString(KEY_AUTH_PREEMPTIVE, Boolean.toString(serverInfo.isAuthPreemptive()));
for (ServerInfo.ResourceInfo addressBook : serverInfo.getAddressBooks())
if (addressBook.isEnabled()) {
bundle.putString(KEY_ADDRESSBOOK_URL, addressBook.getURL());
break;
}
return bundle;
}
@ -123,66 +156,45 @@ public class AccountSettings {
}
}
// address book (CardDAV) settings
public String getAddressBookURL() {
return accountManager.getUserData(account, KEY_ADDRESSBOOK_URL);
}
public String getAddressBookCTag() {
return accountManager.getUserData(account, KEY_ADDRESSBOOK_CTAG);
}
public void setAddressBookCTag(String cTag) {
accountManager.setUserData(account, KEY_ADDRESSBOOK_CTAG, cTag);
}
public VCardVersion getAddressBookVCardVersion() {
VCardVersion version = VCardVersion.V3_0;
String versionStr = accountManager.getUserData(account, KEY_ADDRESSBOOK_VCARD_VERSION);
if (versionStr != null)
version = VCardVersion.valueOfByStr(versionStr);
return version;
}
public void setAddressBookVCardVersion(VCardVersion version) {
accountManager.setUserData(account, KEY_ADDRESSBOOK_VCARD_VERSION, version.getVersion());
}
// update from previous account settings
private void update(int fromVersion) {
Log.i(TAG, "Account settings must be updated from v" + fromVersion + " to v" + CURRENT_VERSION);
for (int toVersion = CURRENT_VERSION; toVersion > fromVersion; toVersion--)
update(fromVersion, toVersion);
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++)
updateTo(toVersion);
}
private void update(int fromVersion, int toVersion) {
Log.i(TAG, "Updating account settings from v" + fromVersion + " to " + toVersion);
private void updateTo(int toVersion) {
final int fromVersion = toVersion - 1;
Constants.log.info("Updating account settings from v" + fromVersion + " to " + toVersion);
try {
if (fromVersion == 0 && toVersion == 1)
update_0_1();
else
Log.wtf(TAG, "Don't know how to update settings from v" + fromVersion + " to v" + toVersion);
switch (toVersion) {
case 1:
update_0_1();
break;
case 2:
update_1_2();
break;
default:
Constants.log.error("Don't know how to update settings from v" + fromVersion + " to v" + toVersion);
}
} catch(Exception e) {
Log.e(TAG, "Couldn't update account settings (DAVdroid will probably crash)!", e);
Constants.log.error("Couldn't update account settings (DAVdroid will probably crash)!", e);
}
}
private void update_0_1() throws URISyntaxException {
String v0_principalURL = accountManager.getUserData(account, "principal_url"),
v0_addressBookPath = accountManager.getUserData(account, "addressbook_path");
Log.d(TAG, "Old principal URL = " + v0_principalURL);
Log.d(TAG, "Old address book path = " + v0_addressBookPath);
Constants.log.debug("Old principal URL = " + v0_principalURL);
Constants.log.debug("Old address book path = " + v0_addressBookPath);
URI principalURI = new URI(v0_principalURL);
// update address book
if (v0_addressBookPath != null) {
String addressBookURL = principalURI.resolve(v0_addressBookPath).toASCIIString();
Log.d(TAG, "New address book URL = " + addressBookURL);
Constants.log.debug("New address book URL = " + addressBookURL);
accountManager.setUserData(account, "addressbook_url", addressBookURL);
}
@ -197,7 +209,7 @@ public class AccountSettings {
int id = cursor.getInt(0);
String v0_path = cursor.getString(1),
v1_url = principalURI.resolve(v0_path).toASCIIString();
Log.d(TAG, "Updating calendar #" + id + " name: " + v0_path + " -> " + v1_url);
Constants.log.debug("Updating calendar #" + id + " name: " + v0_path + " -> " + v1_url);
Uri calendar = ContentUris.appendId(Calendars.CONTENT_URI.buildUpon()
.appendQueryParameter(Calendars.ACCOUNT_NAME, account.name)
.appendQueryParameter(Calendars.ACCOUNT_TYPE, account.type)
@ -205,14 +217,42 @@ public class AccountSettings {
ContentValues newValues = new ContentValues(1);
newValues.put(Calendars.NAME, v1_url);
if (resolver.update(calendar, newValues, null, null) != 1)
Log.e(TAG, "Number of modified calendars != 1");
Constants.log.debug("Number of modified calendars != 1");
}
Log.d(TAG, "Cleaning old principal URL and address book path");
accountManager.setUserData(account, "principal_url", null);
accountManager.setUserData(account, "addressbook_path", null);
Log.d(TAG, "Updated settings successfully!");
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "1");
}
private void update_1_2() throws ContactsStorageException {
/* - KEY_ADDRESSBOOK_URL ("addressbook_url"),,
- 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);
if (provider != null) {
LocalAddressBook addr = new LocalAddressBook(account, provider);
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);
}
// store current Android version
accountManager.setUserData(account, KEY_LAST_ANDROID_VERSION, String.valueOf(Build.VERSION.SDK_INT));
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "2");
}
}

@ -16,13 +16,14 @@ import android.os.Bundle;
import android.provider.CalendarContract.Calendars;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -54,13 +55,11 @@ import lombok.Cleanup;
public class CalendarSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 30,
NOTIFICATION_ID = 2;
protected static final int MAX_MULTIGET = 20;
public CalendarSyncManager(Context context, Account account, Bundle extras, SyncResult result, LocalCalendar calendar) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_CALENDAR_SYNC, context, account, extras, result);
localCollection = calendar;
}
@ -126,7 +125,7 @@ public class CalendarSyncManager extends SyncManager {
// download new/updated iCalendars from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + Joiner.on(" + ").join(bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET

@ -13,9 +13,7 @@ import android.content.ContentProviderClient;
import android.content.Context;
import android.content.SyncResult;
import android.os.Bundle;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
@ -23,6 +21,9 @@ import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -30,8 +31,6 @@ import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import at.bitfire.dav4android.DavAddressBook;
import at.bitfire.dav4android.DavResource;
@ -56,27 +55,25 @@ import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
public class ContactsSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 10,
NOTIFICATION_ID = 1;
protected static final int MAX_MULTIGET = 10;
final protected ContentProviderClient provider;
protected boolean hasVCard4;
public ContactsSyncManager(Context context, Account account, Bundle extras, ContentProviderClient provider, SyncResult result) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_CONTACTS_SYNC, context, account, extras, result);
this.provider = provider;
}
@Override
protected void prepare() {
collectionURL = HttpUrl.parse(settings.getAddressBookURL());
davCollection = new DavAddressBook(httpClient, collectionURL);
protected void prepare() throws ContactsStorageException {
// prepare local address book
localCollection = new LocalAddressBook(account, provider);
collectionURL = HttpUrl.parse(localAddressBook().getURL());
davCollection = new DavAddressBook(httpClient, collectionURL);
}
@Override
@ -122,7 +119,7 @@ public class ContactsSyncManager extends SyncManager {
// download new/updated VCards from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + TextUtils.join(" + ", bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET

@ -204,6 +204,9 @@ abstract public class SyncManager {
.setContentTitle(context.getString(R.string.sync_error_title, account.name))
.setContentIntent(PendingIntent.getActivity(context, 0, detailsIntent, PendingIntent.FLAG_UPDATE_CURRENT));
if (Build.VERSION.SDK_INT >= 20)
builder.setLocalOnly(true);
try {
String[] phases = context.getResources().getStringArray(R.array.sync_error_phases);
String message = context.getString(messageString, phases[syncPhase]);
@ -225,7 +228,7 @@ abstract public class SyncManager {
}
abstract protected void prepare();
abstract protected void prepare() throws ContactsStorageException;
abstract protected void queryCapabilities() throws IOException, HttpException, DavException, CalendarStorageException, ContactsStorageException;

@ -15,13 +15,13 @@ import android.content.SyncResult;
import android.os.Bundle;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.dmfs.provider.tasks.TaskContract.TaskLists;
import java.io.ByteArrayInputStream;
@ -56,15 +56,13 @@ import lombok.Cleanup;
public class TasksSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 30,
NOTIFICATION_ID = 3;
protected static final int MAX_MULTIGET = 30;
final protected TaskProvider provider;
public TasksSyncManager(Context context, Account account, Bundle extras, TaskProvider provider, SyncResult result, LocalTaskList taskList) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_TASK_SYNC, context, account, extras, result);
this.provider = provider;
localCollection = taskList;
}
@ -124,7 +122,7 @@ public class TasksSyncManager extends SyncManager {
// download new/updated iCalendars from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + Joiner.on(" + ").join(bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET

@ -23,18 +23,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import com.google.common.base.Throwables;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
import at.bitfire.dav4android.exception.HttpException;
import at.bitfire.davdroid.BuildConfig;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.R;
import lombok.Cleanup;
public class DebugInfoActivity extends Activity {
public static final String
@ -141,7 +135,8 @@ public class DebugInfoActivity extends Activity {
if (exception != null) {
report.append("STACK TRACE\n");
report.append(Throwables.getStackTraceAsString(exception));
for (String stackTrace : ExceptionUtils.getRootCauseStackTrace(exception))
report.append(stackTrace + "\n");
}
return report.toString();

@ -141,22 +141,5 @@ public class AccountFragment extends PreferenceFragment {
prefSyncTasks.setSummary(R.string.settings_sync_summary_not_available);
}
// category: address book
final CheckBoxPreference prefVCard4 = (CheckBoxPreference) findPreference("vcard4_support");
if (settings.getAddressBookURL() != null) { // does this account even have an address book?
final VCardVersion vCardVersion = settings.getAddressBookVCardVersion();
prefVCard4.setChecked(vCardVersion == VCardVersion.V4_0);
prefVCard4.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// don't change the value (it's not really a setting, only a display)
return false;
}
});
} else {
// account doesn't have an adress book, disable contact settings
prefVCard4.setEnabled(false);
}
}
}

@ -104,6 +104,11 @@ public class AccountDetailsFragment extends Fragment implements TextWatcher {
public void createLocalCollection(Account account, ServerInfo.ResourceInfo resource) throws ContactsStorageException {
@Cleanup("release") ContentProviderClient provider = getActivity().getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
LocalAddressBook addressBook = new LocalAddressBook(account, provider);
// set URL
addressBook.setURL(resource.getURL());
// set Settings
ContentValues settings = new ContentValues(2);
settings.put(ContactsContract.Settings.SHOULD_SYNC, 1);
settings.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1);

@ -143,7 +143,12 @@
<string name="settings_carddav_vcard4_support">VCard 4.0-Unterstützung</string>
<string name="settings_carddav_vcard4_supported">Kontakte werden als VCard 4.0 gesendet</string>
<string name="settings_carddav_vcard4_not_supported">Kontakte werden als VCard 3.0 gesendet</string>
<string name="settings_android_update_title">Neue Android-Version</string>
<string name="settings_android_update_description">Die Änderung der Android-Version kann einen Einfluss auf DAVdroid haben. Falls etwas nicht funktioniert, löschen Sie bitte Ihre DAVdroid-Accounts und fügen Sie sie neu hinzu.</string>
<string name="settings_version_update_title">Einstellungen aktualisiert</string>
<string name="settings_version_update_description">Interne Einstellungen wurden aktualisiert. Falls etwas nicht funktioniert, löschen Sie bitte Ihre DAVdroid-Accounts und fügen Sie sie neu hinzu.</string>
<string name="setup_select_collections">DAVdroid: Ordner auswählen</string>
<string name="setup_neither_caldav_nor_carddav">An dieser Adresse konnte kein CalDAV- oder CardDAV-Dienst gefunden werden.</string>
<string name="setup_add_account">Konto hinzufügen</string>
@ -178,9 +183,9 @@
<string name="setup_read_only">schreibgeschützt</string>
<string name="sync_error_title">Synchronisierung von %s fehlgeschlagen</string>
<string name="sync_error">Fehler beim %1$s</string>
<string name="sync_error_http_dav">Serverfehler</string>
<string name="sync_error_local_storage">Datenbank-Fehler</string>
<string name="sync_error">Fehler beim %s</string>
<string name="sync_error_http_dav">Serverfehler beim %s</string>
<string name="sync_error_local_storage">Datenbank-Fehler beim %s</string>
<string-array name="sync_error_phases">
<item>Vorbereiten der Synchronisierung</item>
<item>Abfragen der Server-Fähigkeiten</item>

@ -159,6 +159,11 @@
<string name="settings_carddav_vcard4_supported">Contacts are sent in VCard 4.0 format</string>
<string name="settings_carddav_vcard4_not_supported">Contacts are sent in VCard 3.0 format</string>
<string name="settings_android_update_title">Android version update</string>
<string name="settings_android_update_description">Android version updates may have an impact on how DAVdroid works. If there are problems, please delete your DAVdroid accounts and add them again.</string>
<string name="settings_version_update_title">Settings have been updated</string>
<string name="settings_version_update_description">Internal settings have been updated. If there are problems, please delete your DAVdroid accounts and add them again.</string>
<string name="setup_select_collections">DAVdroid: Select collections</string>
<string name="setup_neither_caldav_nor_carddav">No CalDAV-/CardDAV service is available at this location.</string>
<string name="setup_add_account">Add account</string>
@ -193,9 +198,9 @@
<!-- sync errors and DebugInfoActivity -->
<string name="debug_info_title">Debug info</string>
<string name="sync_error_title">Synchronization of %s failed</string>
<string name="sync_error">Error while %1$s</string>
<string name="sync_error_http_dav">Server error</string>
<string name="sync_error_local_storage">Database error</string>
<string name="sync_error">Error while %s</string>
<string name="sync_error_http_dav">Server error while %s</string>
<string name="sync_error_local_storage">Database error while %s</string>
<string-array name="sync_error_phases">
<item>preparing synchronization</item>
<item>querying capabilities</item>

@ -59,15 +59,10 @@
</PreferenceCategory>
<!--
<PreferenceCategory android:title="@string/settings_carddav">
<CheckBoxPreference
android:key="vcard4_support"
android:title="@string/settings_carddav_vcard4_support"
android:persistent="false"
android:summaryOn="@string/settings_carddav_vcard4_supported"
android:summaryOff="@string/settings_carddav_vcard4_not_supported" />
</PreferenceCategory>
-->
</PreferenceScreen>

@ -1 +1 @@
Subproject commit 6fc7f30b614ecb23b6fa66b6fd848fd6ddc4bafe
Subproject commit 429648cfae534dd0476f813c94ab1cae1f140223

@ -1 +1 @@
Subproject commit 624287708eb7f093d2ddf2012e2c2c124cd6e206
Subproject commit 662c48c40ad66e9a77f4f4792587dc04ecc4a74e

@ -1 +1 @@
Subproject commit 83ba3128913ba6e57d021ad003bf992100baae43
Subproject commit 18b26fe48896b2683b1e04e8df4464f5ceacf8f3
Loading…
Cancel
Save