package com.valtech.contactsync;

import android.accounts.Account;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.provider.ContactsContract;

import java.util.NoSuchElementException;

public class GroupRepository {
  private final ContentResolver resolver;

  public GroupRepository(ContentResolver resolver) {
    this.resolver = resolver;
  }

  public long ensureGroup(Account account, String groupTitle) {
    try {
      return getGroupId(account, groupTitle);
    } catch (NoSuchElementException e) {
      createGroup(account, groupTitle);
      return getGroupId(account, groupTitle);
    }
  }

  private long getGroupId(Account account, String groupTitle) {
    Cursor cursor = null;

    try {
      cursor = resolver.query(ContactsContract.Groups.CONTENT_URI,
        new String[]{ContactsContract.Groups._ID},
        ContactsContract.Groups.ACCOUNT_TYPE + " = ? AND " + ContactsContract.Groups.TITLE + " = ?",
        new String[]{account.type, groupTitle},
        null);

      if (cursor.moveToNext()) return cursor.getLong(0);
    } finally {
      if (cursor != null) cursor.close();
    }

    throw new NoSuchElementException();
  }

  private void createGroup(Account account, String groupTitle) {
    ContentValues values = new ContentValues();

    values.put(ContactsContract.Groups.TITLE, groupTitle);
    values.put(ContactsContract.Groups.GROUP_VISIBLE, 1);
    values.put(ContactsContract.Groups.SHOULD_SYNC, 0);

    values.put(ContactsContract.Groups.ACCOUNT_NAME, account.name);
    values.put(ContactsContract.Groups.ACCOUNT_TYPE, account.type);

    resolver.insert(ContactsContract.Groups.CONTENT_URI, values);
  }
}

@@ -170,16 +170,40 @@
 Cursor;%0A
+import android.net.Uri;%0A
 import a
@@ -310,16 +310,397 @@
 itory %7B%0A
+  // Appending this query parameter means we perform as operations as a sync adapter, not as a user.%0A  // http://developer.android.com/reference/android/provider/ContactsContract.html#CALLER_IS_SYNCADAPTER%0A  private static final Uri GROUPS_CONTENT_URI = ContactsContract.Groups.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, %22true%22).build();%0A%0A
   privat
@@ -2080,32 +2080,15 @@
 ert(
-ContactsContract.Groups.
+GROUPS_
 CONT

Use CALLER_IS_SYNCADAPTER also on group uri