mirror of
https://github.com/etesync/android
synced 2024-12-23 07:08:16 +00:00
Better group support
* change group methods to less specific values * new account settings version: change group method to CATEGORIES for updated accounts * change group method from CATEGORIES to GROUP_VCARDS automatically when a group VCard is received GUI: * AccountSettings: disable CalDAV/CardDAV options when the corresponding service is not available * AccountSettings: new option to choose contact group method * account setup: allow to choose contact group method at account creation
This commit is contained in:
parent
be2e15e463
commit
389af2b738
@ -50,7 +50,7 @@ import lombok.Cleanup;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
public class AccountSettings {
|
||||
private final static int CURRENT_VERSION = 3;
|
||||
private final static int CURRENT_VERSION = 4;
|
||||
private final static String
|
||||
KEY_SETTINGS_VERSION = "version",
|
||||
|
||||
@ -80,10 +80,8 @@ public class AccountSettings {
|
||||
private final static String KEY_MANAGE_CALENDAR_COLORS = "manage_calendar_colors";
|
||||
|
||||
/** Contact group method:
|
||||
automatic VCard4 if server supports VCard 4, VCard3 otherwise (default value)
|
||||
VCard3 adds a contact's groups to its CATEGORIES / interprets a contact's CATEGORIES as groups
|
||||
VCard4 uses groups as defined in VCard 4 (KIND/MEMBER properties)
|
||||
Apple uses Apple-proprietary X-ADDRESSBOOK-KIND/-MEMBER properties
|
||||
value = null (not existing) groups as separate VCards (default)
|
||||
"CATEGORIES" groups are per-contact CATEGORIES
|
||||
*/
|
||||
private final static String KEY_CONTACT_GROUP_METHOD = "contact_group_method";
|
||||
|
||||
@ -240,11 +238,11 @@ public class AccountSettings {
|
||||
final String name = accountManager.getUserData(account, KEY_CONTACT_GROUP_METHOD);
|
||||
return name != null ?
|
||||
GroupMethod.valueOf(name) :
|
||||
GroupMethod.AUTOMATIC;
|
||||
GroupMethod.GROUP_VCARDS;
|
||||
}
|
||||
|
||||
public void setGroupMethod(@NonNull GroupMethod method) {
|
||||
final String name = GroupMethod.AUTOMATIC.equals(method) ? null : method.name();
|
||||
final String name = method == GroupMethod.GROUP_VCARDS ? null : method.name();
|
||||
accountManager.setUserData(account, KEY_CONTACT_GROUP_METHOD, name);
|
||||
}
|
||||
|
||||
@ -424,6 +422,11 @@ public class AccountSettings {
|
||||
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "3");
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "Recycle", "unused" })
|
||||
private void update_3_4() {
|
||||
setGroupMethod(GroupMethod.CATEGORIES);
|
||||
}
|
||||
|
||||
|
||||
public static class AppUpdatedReceiver extends BroadcastReceiver {
|
||||
|
||||
|
@ -164,6 +164,14 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
|
||||
group.delete();
|
||||
}
|
||||
|
||||
public void removeGroups() throws ContactsStorageException {
|
||||
try {
|
||||
provider.delete(syncAdapterURI(Groups.CONTENT_URI), null, null);
|
||||
} catch(RemoteException e) {
|
||||
throw new ContactsStorageException("Couldn't remove all groups", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SYNC STATE
|
||||
|
||||
|
@ -19,6 +19,7 @@ import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
|
||||
import android.provider.ContactsContract.Groups;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.provider.ContactsContract.RawContacts.Data;
|
||||
import android.provider.ContactsContract.RawContactsEntity;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
|
@ -83,13 +83,13 @@ import okhttp3.ResponseBody;
|
||||
* <p></p>Group handling differs according to the {@link #groupMethod}. There are two basic methods to
|
||||
* handle/manage groups:</p>
|
||||
* <ul>
|
||||
* <li>VCard3 {@code CATEGORIES}: groups memberships are attached to each contact and represented as
|
||||
* <li>{@code CATEGORIES}: groups memberships are attached to each contact and represented as
|
||||
* "category". When a group is dirty or has been deleted, all its members have to be set to
|
||||
* dirty, too (because they have to be uploaded without the respective category). This
|
||||
* is done in {@link #prepareDirty()}. Empty groups can be deleted without further processing,
|
||||
* which is done in {@link #postProcess()} because groups may become empty after downloading
|
||||
* updated remoted contacts.</li>
|
||||
* <li>VCard4-style: individual and group contacts (with a list of member UIDs) are
|
||||
* <li>Groups as separate VCards: individual and group contacts (with a list of member UIDs) are
|
||||
* distinguished. When a local group is dirty, its members don't need to be set to dirty.
|
||||
* <ol>
|
||||
* <li>However, when a contact is dirty, it has
|
||||
@ -171,11 +171,9 @@ public class ContactsSyncManager extends SyncManager {
|
||||
App.log.info("Server advertises VCard/4 support: " + hasVCard4);
|
||||
|
||||
groupMethod = settings.getGroupMethod();
|
||||
if (GroupMethod.AUTOMATIC.equals(groupMethod))
|
||||
groupMethod = hasVCard4 ? GroupMethod.VCARD4 : GroupMethod.VCARD3_CATEGORIES;
|
||||
App.log.info("Contact group method: " + groupMethod);
|
||||
|
||||
localAddressBook().includeGroups = !GroupMethod.VCARD3_CATEGORIES.equals(groupMethod);
|
||||
localAddressBook().includeGroups = groupMethod == GroupMethod.GROUP_VCARDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -184,13 +182,14 @@ public class ContactsSyncManager extends SyncManager {
|
||||
|
||||
LocalAddressBook addressBook = localAddressBook();
|
||||
|
||||
if (GroupMethod.VCARD3_CATEGORIES.equals(groupMethod)) {
|
||||
/* VCard3 group handling: groups memberships are represented as contact CATEGORIES */
|
||||
if (groupMethod == GroupMethod.CATEGORIES) {
|
||||
/* groups memberships are represented as contact CATEGORIES */
|
||||
|
||||
// groups with DELETED=1: set all members to dirty, then remove group
|
||||
for (LocalGroup group : addressBook.getDeletedGroups()) {
|
||||
App.log.fine("Removing group " + group + " and marking its members as dirty");
|
||||
group.markMembersDirty();
|
||||
App.log.fine("Finally removing group " + group);
|
||||
// useless because Android deletes group memberships as soon as a group is set to DELETED:
|
||||
// group.markMembersDirty();
|
||||
group.delete();
|
||||
}
|
||||
|
||||
@ -201,7 +200,7 @@ public class ContactsSyncManager extends SyncManager {
|
||||
group.clearDirty(null);
|
||||
}
|
||||
} else {
|
||||
/* VCard4 group handling: there are group contacts and individual contacts */
|
||||
/* groups as separate VCards: there are group contacts and individual contacts */
|
||||
|
||||
// mark groups with changed members as dirty
|
||||
BatchOperation batch = new BatchOperation(addressBook.provider);
|
||||
@ -231,8 +230,8 @@ public class ContactsSyncManager extends SyncManager {
|
||||
LocalContact local = ((LocalContact)resource);
|
||||
contact = local.getContact();
|
||||
|
||||
if (groupMethod == GroupMethod.VCARD3_CATEGORIES) {
|
||||
// VCard3: add groups as CATEGORIES
|
||||
if (groupMethod == GroupMethod.CATEGORIES) {
|
||||
// add groups as CATEGORIES
|
||||
for (long groupID : local.getGroupMemberships()) {
|
||||
try {
|
||||
@Cleanup Cursor c = provider.query(
|
||||
@ -362,7 +361,7 @@ public class ContactsSyncManager extends SyncManager {
|
||||
|
||||
@Override
|
||||
protected void postProcess() throws CalendarStorageException, ContactsStorageException {
|
||||
if (groupMethod == GroupMethod.VCARD3_CATEGORIES) {
|
||||
if (groupMethod == GroupMethod.CATEGORIES) {
|
||||
/* VCard3 group handling: groups memberships are represented as contact CATEGORIES */
|
||||
|
||||
// remove empty groups
|
||||
@ -399,6 +398,13 @@ public class ContactsSyncManager extends SyncManager {
|
||||
|
||||
final Contact newData = contacts[0];
|
||||
|
||||
if (groupMethod == GroupMethod.CATEGORIES && newData.group) {
|
||||
groupMethod = GroupMethod.GROUP_VCARDS;
|
||||
App.log.warning("Received group VCard although group method is CATEGORIES. Deleting all groups; new group method: " + groupMethod);
|
||||
localAddressBook().removeGroups();
|
||||
settings.setGroupMethod(groupMethod);
|
||||
}
|
||||
|
||||
// update local contact, if it exists
|
||||
LocalResource local = localResources.get(fileName);
|
||||
if (local != null) {
|
||||
@ -446,7 +452,7 @@ public class ContactsSyncManager extends SyncManager {
|
||||
syncResult.stats.numInserts++;
|
||||
}
|
||||
|
||||
if (groupMethod == GroupMethod.VCARD3_CATEGORIES && local instanceof LocalContact) {
|
||||
if (groupMethod == GroupMethod.CATEGORIES && local instanceof LocalContact) {
|
||||
// VCard3: update group memberships from CATEGORIES
|
||||
LocalContact contact = (LocalContact)local;
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
|
||||
try {
|
||||
settings = new AccountSettings(getActivity(), account);
|
||||
} catch(InvalidAccountException e) {
|
||||
} catch(InvalidAccountException e) {
|
||||
App.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e);
|
||||
getActivity().finish();
|
||||
return;
|
||||
@ -98,8 +98,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefUserName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.username((String) newValue);
|
||||
refresh(); return false;
|
||||
settings.username((String)newValue);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -107,8 +108,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefPassword.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.password((String) newValue);
|
||||
refresh(); return false;
|
||||
settings.password((String)newValue);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -117,8 +119,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefPreemptive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.preemptiveAuth((Boolean) newValue);
|
||||
refresh(); return false;
|
||||
settings.preemptiveAuth((Boolean)newValue);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -134,8 +137,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefSyncContacts.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.setSyncInterval(ContactsContract.AUTHORITY, Long.parseLong((String) newValue));
|
||||
refresh(); return false;
|
||||
settings.setSyncInterval(ContactsContract.AUTHORITY, Long.parseLong((String)newValue));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -154,8 +158,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefSyncCalendars.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, Long.parseLong((String) newValue));
|
||||
refresh(); return false;
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, Long.parseLong((String)newValue));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -174,8 +179,9 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
prefSyncTasks.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, Long.parseLong((String) newValue));
|
||||
refresh(); return false;
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, Long.parseLong((String)newValue));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -189,7 +195,8 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object wifiOnly) {
|
||||
settings.setSyncWiFiOnly((Boolean)wifiOnly);
|
||||
refresh(); return false;
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -205,68 +212,85 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String ssid = (String)newValue;
|
||||
settings.setSyncWifiOnlySSID(!TextUtils.isEmpty(ssid) ? ssid : null);
|
||||
refresh(); return false;
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// category: CardDAV
|
||||
final SwitchPreferenceCompat prefRFC6868 = (SwitchPreferenceCompat)findPreference("vcard_rfc6868");
|
||||
prefRFC6868.setChecked(settings.getVCardRFC6868());
|
||||
prefRFC6868.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
settings.setVCardRFC6868((Boolean)o);
|
||||
refresh(); return false;
|
||||
}
|
||||
});
|
||||
if (syncIntervalContacts != null) {
|
||||
prefRFC6868.setChecked(settings.getVCardRFC6868());
|
||||
prefRFC6868.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
settings.setVCardRFC6868((Boolean)o);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else
|
||||
prefRFC6868.setEnabled(false);
|
||||
|
||||
final ListPreference prefGroupMethod = (ListPreference)findPreference("contact_group_method");
|
||||
if (syncIntervalContacts != null) {
|
||||
prefGroupMethod.setValue(settings.getGroupMethod().name());
|
||||
prefGroupMethod.setSummary(prefGroupMethod.getEntry());
|
||||
prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
String name = (String)o;
|
||||
settings.setGroupMethod(GroupMethod.valueOf(name));
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else
|
||||
prefGroupMethod.setEnabled(false);
|
||||
|
||||
// category: CalDAV
|
||||
final EditTextPreference prefTimeRangePastDays = (EditTextPreference)findPreference("time_range_past_days");
|
||||
Integer pastDays = settings.getTimeRangePastDays();
|
||||
if (pastDays != null) {
|
||||
prefTimeRangePastDays.setText(pastDays.toString());
|
||||
prefTimeRangePastDays.setSummary(getResources().getQuantityString(R.plurals.settings_sync_time_range_past_days, pastDays, pastDays));
|
||||
} else {
|
||||
prefTimeRangePastDays.setText(null);
|
||||
prefTimeRangePastDays.setSummary(R.string.settings_sync_time_range_past_none);
|
||||
}
|
||||
prefTimeRangePastDays.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
int days;
|
||||
try {
|
||||
days = Integer.parseInt((String)newValue);
|
||||
} catch(NumberFormatException ignored) {
|
||||
days = -1;
|
||||
}
|
||||
settings.setTimeRangePastDays(days < 0 ? null : days);
|
||||
refresh(); return false;
|
||||
if (syncIntervalCalendars != null) {
|
||||
Integer pastDays = settings.getTimeRangePastDays();
|
||||
if (pastDays != null) {
|
||||
prefTimeRangePastDays.setText(pastDays.toString());
|
||||
prefTimeRangePastDays.setSummary(getResources().getQuantityString(R.plurals.settings_sync_time_range_past_days, pastDays, pastDays));
|
||||
} else {
|
||||
prefTimeRangePastDays.setText(null);
|
||||
prefTimeRangePastDays.setSummary(R.string.settings_sync_time_range_past_none);
|
||||
}
|
||||
});
|
||||
prefTimeRangePastDays.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
int days;
|
||||
try {
|
||||
days = Integer.parseInt((String)newValue);
|
||||
} catch(NumberFormatException ignored) {
|
||||
days = -1;
|
||||
}
|
||||
settings.setTimeRangePastDays(days < 0 ? null : days);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else
|
||||
prefTimeRangePastDays.setEnabled(false);
|
||||
|
||||
final SwitchPreferenceCompat prefManageColors = (SwitchPreferenceCompat)findPreference("manage_calendar_colors");
|
||||
prefManageColors.setChecked(settings.getManageCalendarColors());
|
||||
prefManageColors.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.setManageCalendarColors((Boolean)newValue);
|
||||
refresh(); return false;
|
||||
}
|
||||
});
|
||||
if (syncIntervalCalendars != null || syncIntervalTasks != null) {
|
||||
prefManageColors.setChecked(settings.getManageCalendarColors());
|
||||
prefManageColors.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
settings.setManageCalendarColors((Boolean)newValue);
|
||||
refresh();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else
|
||||
prefManageColors.setEnabled(false);
|
||||
|
||||
// category: CardDAV
|
||||
final ListPreference prefGroupMethod = (ListPreference)findPreference("contact_group_method");
|
||||
prefGroupMethod.setValue(settings.getGroupMethod().name());
|
||||
prefGroupMethod.setSummary(prefGroupMethod.getEntry());
|
||||
prefGroupMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
String name = (String)o;
|
||||
settings.setGroupMethod(GroupMethod.valueOf(name));
|
||||
refresh(); return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.logging.Level;
|
||||
@ -42,6 +43,7 @@ import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
||||
import at.bitfire.davdroid.model.ServiceDB.Services;
|
||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||
import at.bitfire.ical4android.TaskProvider;
|
||||
import at.bitfire.vcard4android.GroupMethod;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class AccountDetailsFragment extends Fragment {
|
||||
@ -49,6 +51,9 @@ public class AccountDetailsFragment extends Fragment {
|
||||
private static final String KEY_CONFIG = "config";
|
||||
private static final int DEFAULT_SYNC_INTERVAL = 4 * 3600; // 4 hours
|
||||
|
||||
Spinner spnrGroupMethod;
|
||||
|
||||
|
||||
public static AccountDetailsFragment newInstance(DavResourceFinder.Configuration config) {
|
||||
AccountDetailsFragment frag = new AccountDetailsFragment();
|
||||
Bundle args = new Bundle(1);
|
||||
@ -57,6 +62,7 @@ public class AccountDetailsFragment extends Fragment {
|
||||
return frag;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
final View v = inflater.inflate(R.layout.login_account_details, container, false);
|
||||
@ -74,6 +80,10 @@ public class AccountDetailsFragment extends Fragment {
|
||||
final EditText editName = (EditText)v.findViewById(R.id.account_name);
|
||||
editName.setText(config.userName);
|
||||
|
||||
// CardDAV-specific
|
||||
v.findViewById(R.id.carddav).setVisibility(config.cardDAV != null ? View.VISIBLE : View.GONE);
|
||||
spnrGroupMethod = (Spinner)v.findViewById(R.id.contact_group_method);
|
||||
|
||||
Button btnCreate = (Button)v.findViewById(R.id.create_account);
|
||||
btnCreate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -114,25 +124,39 @@ public class AccountDetailsFragment extends Fragment {
|
||||
Intent refreshIntent = new Intent(getActivity(), DavService.class);
|
||||
refreshIntent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
||||
|
||||
db.beginTransactionNonExclusive();
|
||||
if (config.cardDAV != null) {
|
||||
// insert CardDAV service
|
||||
long id = insertService(db, accountName, Services.SERVICE_CARDDAV, config.cardDAV);
|
||||
|
||||
// start CardDAV service detection (refresh collections)
|
||||
refreshIntent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, id);
|
||||
getActivity().startService(refreshIntent);
|
||||
|
||||
// initial CardDAV account settings
|
||||
int idx = spnrGroupMethod.getSelectedItemPosition();
|
||||
String groupMethodName = getResources().getStringArray(R.array.settings_contact_group_method_values)[idx];
|
||||
settings.setGroupMethod(GroupMethod.valueOf(groupMethodName));
|
||||
|
||||
// enable contact sync
|
||||
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1);
|
||||
settings.setSyncInterval(ContactsContract.AUTHORITY, DEFAULT_SYNC_INTERVAL);
|
||||
} else
|
||||
// disable contact sync when CardDAV is not available
|
||||
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);
|
||||
|
||||
if (config.calDAV != null) {
|
||||
// insert CalDAV service
|
||||
long id = insertService(db, accountName, Services.SERVICE_CALDAV, config.calDAV);
|
||||
|
||||
// start CalDAV service detection (refresh collections)
|
||||
refreshIntent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, id);
|
||||
getActivity().startService(refreshIntent);
|
||||
|
||||
// enable calendar sync
|
||||
ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 1);
|
||||
settings.setSyncInterval(CalendarContract.AUTHORITY, DEFAULT_SYNC_INTERVAL);
|
||||
|
||||
// enable task sync, if possible
|
||||
if (Build.VERSION.SDK_INT >= 23 || LocalTaskList.tasksProviderAvailable(getContext())) {
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 1);
|
||||
settings.setSyncInterval(TaskProvider.ProviderName.OpenTasks.authority, DEFAULT_SYNC_INTERVAL);
|
||||
@ -141,15 +165,13 @@ public class AccountDetailsFragment extends Fragment {
|
||||
// because otherwise, there will be a non-catchable SecurityException as soon as OpenTasks is installed
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 0);
|
||||
} else {
|
||||
// disable calendar and task sync when CalDAV is not available
|
||||
ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 0);
|
||||
ContentResolver.setIsSyncable(account, TaskProvider.ProviderName.OpenTasks.authority, 0);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} catch(InvalidAccountException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't access account settings", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -87,6 +87,7 @@ public class LoginCredentialsFragment extends Fragment implements CompoundButton
|
||||
boolean loginByEmail = buttonView == radioUseEmail;
|
||||
emailDetails.setVisibility(loginByEmail ? View.VISIBLE : View.GONE);
|
||||
urlDetails.setVisibility(loginByEmail ? View.GONE : View.VISIBLE);
|
||||
(loginByEmail ? editEmailAddress : editBaseURL).requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,32 @@
|
||||
android:inputType="textEmailAddress"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/account_email_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/login_account_name_info"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/carddav"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/login_account_contact_group_method"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/contact_group_method"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/settings_contact_group_method_entries"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
@ -126,6 +126,7 @@
|
||||
<string name="login_create_account">Create account</string>
|
||||
<string name="login_account_name">Account name</string>
|
||||
<string name="login_account_name_info">Use your email address as account name because Android will use the account name as ORGANIZER field for events you create. You can\'t have two accounts with the same name.</string>
|
||||
<string name="login_account_contact_group_method">Contact group method:</string>
|
||||
<string name="login_account_name_required">Account name required</string>
|
||||
<string name="login_account_not_created">Account could not be created</string>
|
||||
|
||||
@ -182,16 +183,12 @@
|
||||
<string name="settings_carddav">CardDAV</string>
|
||||
<string name="settings_contact_group_method">Contact group method</string>
|
||||
<string-array name="settings_contact_group_method_values">
|
||||
<item>AUTOMATIC</item>
|
||||
<item>VCARD3_CATEGORIES</item>
|
||||
<item>VCARD4</item>
|
||||
<item>X_ADDRESSBOOK_SERVER</item>
|
||||
<item>GROUP_VCARDS</item>
|
||||
<item>CATEGORIES</item>
|
||||
</string-array>
|
||||
<string-array name="settings_contact_group_method_entries">
|
||||
<item>Automatic (VCard3/VCard4)</item>
|
||||
<item>VCard3 only (CATEGORIES)</item>
|
||||
<item>VCard4 only (KIND/MEMBER)</item>
|
||||
<item>Apple (X-ADDRESSBOOK-SERVER)</item>
|
||||
<item>Groups are separate VCards</item>
|
||||
<item>Groups are per-contact categories</item>
|
||||
</string-array>
|
||||
<string name="settings_rfc6868_for_vcards">Use RFC6868 for VCards</string>
|
||||
<string name="settings_rfc6868_for_vcards_on">Double quotes can be used in parameter values</string>
|
||||
|
3
scripts/fetch-db.sh
Executable file
3
scripts/fetch-db.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
cd ~/tmp
|
||||
adb pull /data/data/com.android.providers.contacts/databases/contacts2.db
|
@ -1 +1 @@
|
||||
Subproject commit 38e24e8a19df339618ec33afb294a3e4a61b3cbe
|
||||
Subproject commit 02eae2c067c8fca4a9cf9f0e324af9bb4b91d3d0
|
Loading…
Reference in New Issue
Block a user