1

im trying to add new contacts to the phone but he does only the first 12 items. i want to try all current 36 items and maybe more add to the phone contacts.

            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("[[DEBUG]] [DW-UPDATE] LINE: " + line);
                String[] split = line.split(";", -1);

                split[2] = split[2].replace("/", "").replace("-", "");

                if (!contactExists(mActivity, split[2])) {
                    ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                        .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                        .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                        .withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DISABLED)
                    .build());
                    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, Integer.valueOf(split[0]))
                        .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, split[1])
                    .build());
                    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, Integer.valueOf(split[0]))
                        .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, split[2])
                        .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                    .build());

                    try {
                        mActivity.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

function contactExists:

public boolean contactExists(Activity _activity, String number) {
    Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
    String[] mPhoneNumberProjection = { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup.DISPLAY_NAME };
    Cursor cur = _activity.getContentResolver().query(lookupUri, mPhoneNumberProjection, null, null, null);
    try {
        if (cur.moveToFirst()) {
            return true;
        }
    } finally {
        if (cur != null)
            cur.close();
    }
    return false;
}// contactExists

what i must do, to work this better?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • Just to confirm, how many times are you seeing `[[DEBUG]] [DW-UPDATE] LINE:` appear? I'd also recommend using [`Log.d()`](https://developer.android.com/studio/debug/am-logcat.html) instead to print log messages to Android's Logcat. – Michael Dodd Dec 19 '17 at 12:16
  • all 36 items print the message. What is the different between Log.d and System.out ? – Florian Schmidt Dec 19 '17 at 12:21
  • `System.out`, traditionally for logging to the Java console, gets redirected to `Log.i()` in more recent versions of Android, but previously it didn't get picked up by Android's logging tool `Logcat`. Using `Log` ensures that logging messages are passed to logcat. See also: https://stackoverflow.com/a/2220559/469080 – Michael Dodd Dec 19 '17 at 12:26
  • Using `Log` also allows for [different logging levels](https://developer.android.com/studio/debug/am-logcat.html#level) based on the severity of what you're logging (e.g. debug message, warning, error) – Michael Dodd Dec 19 '17 at 12:27
  • I have a feeling you're using the wrong back reference. Just after your `if` statement, add `int backref = ops.size();`, and use `backref` instead of `split[0]`. Not confident enough to call it an answer, but give it a go. – Michael Dodd Dec 19 '17 at 12:37
  • oh thanks you. that was my mistake. it works perfect! – Florian Schmidt Dec 19 '17 at 12:48
  • Cheers, full answer added. Please upvote and accept if you find it useful. – Michael Dodd Dec 19 '17 at 13:07

1 Answers1

1

Your problem is with your back references when adding the additional contact data. The back reference should refer to the position of your RawContacts.CONTENT_URI insert within your list of operations (ops), not the position of the contact within your raw data file. You can fix this by keeping track of the size of ops through each iteration:

if (!contactExists(mActivity, split[2])) {
    int backRef = ops.size();

    ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
        .withValue(...)
        .build());

    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRef)
        .withValue(...)
        .build()

    .build());
    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRef)
        .withValue(...)
    .build());

    try {
        mActivity.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Michael Dodd
  • 10,102
  • 12
  • 51
  • 64