23

I am writing an app that lets the user remove contacts from their Android device and store them in a separate database. They should also be able to restore the contacts to their phone, but I am having trouble with this part. I retrieve the contact information from my database and create a contact object that contains the contact ID, lookup key, structured name, organization, an array list of phone objects (which contain the phone number and type), etc. It's all there. My function to restore that information to the phone looks like this:

public void addContact(Contact contact)
{
    ContentValues values = new ContentValues();
    values.put("contact_id", contact.getContactId());
    values.put("lookup", contact.getLookupKey());
    values.put("mimetype", StructuredName.CONTENT_ITEM_TYPE);
    values.put("data1", contact.getStructuredName().getDisplayName());
    values.put("data2", contact.getStructuredName().getGivenName());
    values.put("data3", contact.getStructuredName().getFamilyName());
    values.put("data4", contact.getStructuredName().getPrefix());
    values.put("data5", contact.getStructuredName().getMiddleName());
    values.put("data6", contact.getStructuredName().getSuffix());
    context.getContentResolver().insert(Data.CONTENT_URI, values);
}

And, well, that's where the app crashes. I used this method to insert data into my database without any problems, and I can verify that it is being stored correctly. So my guess is that there is a better way than this to insert contacts into the device, but I have no idea what that would be. Could someone give me an example of programmatically creating and inserting a contact into the user's device? I'd be satisfied even if I could see a contact with just a display name being created.

In case it matters, I also tried putting this code above the insertion of the structured name, but to no avail:

values.put("_id", contact.getContactId());
values.put("lookup", contact.getLookupKey());
values.put("display_name", contact.getStructuredName().getDisplayName());
context.getContentResolver().insert(Contacts.CONTENT_URI, values);
values.clear();

Edit: Here is my logcat error log for when the app crashes:

05-07 20:31:53.941: E/Trace(819): error opening trace file: No such file or directory (2)
05-07 20:34:39.035: D/AndroidRuntime(853): Shutting down VM
05-07 20:34:39.048: W/dalvikvm(853): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-07 20:34:39.197: E/AndroidRuntime(853): FATAL EXCEPTION: main
05-07 20:34:39.197: E/AndroidRuntime(853): java.lang.NullPointerException
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.os.Parcel.readException(Parcel.java:1431)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.content.ContentProviderProxy.insert(ContentProviderNative.java:420)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.content.ContentResolver.insert(ContentResolver.java:866)
05-07 20:34:39.197: E/AndroidRuntime(853):  at com.protextyou.contacts.ContactHandler.addContact(ContactHandler.java:58)
05-07 20:34:39.197: E/AndroidRuntime(853):  at com.protextyou.StartPage$12.onClick(StartPage.java:542)
05-07 20:34:39.197: E/AndroidRuntime(853):  at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.os.Looper.loop(Looper.java:137)
05-07 20:34:39.197: E/AndroidRuntime(853):  at android.app.ActivityThread.main(ActivityThread.java:5041)
05-07 20:34:39.197: E/AndroidRuntime(853):  at java.lang.reflect.Method.invokeNative(Native Method)
05-07 20:34:39.197: E/AndroidRuntime(853):  at java.lang.reflect.Method.invoke(Method.java:511)
05-07 20:34:39.197: E/AndroidRuntime(853):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-07 20:34:39.197: E/AndroidRuntime(853):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-07 20:34:39.197: E/AndroidRuntime(853):  at dalvik.system.NativeStart.main(Native Method)
Cheddar
  • 329
  • 2
  • 3
  • 9
  • If it crashes, there should be a stack trace in the log. Please post the logcat. – Aleks G May 07 '13 at 08:23
  • Er, I am not exactly sure which part to post. A bunch of errors pop up in the logcat, so here's the top few: `05-07 09:07:02.334: E/Trace(3052): error opening trace file: No such file or directory (2)` `05-07 09:07:21.483: E/AndroidRuntime(3052): FATAL EXCEPTION: main` `05-07 09:07:21.483: E/AndroidRuntime(3052): java.lang.NullPointerException` `05-07 09:07:21.483: E/AndroidRuntime(3052): at android.os.Parcel.readException(Parcel.java:1431)` `05-07 09:07:21.483: E/AndroidRuntime(3052): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)` – Cheddar May 07 '13 at 09:10
  • the part about `NullPointerException` is the one to post. Edit your question and add the _full_ stack trace, not just the first two rows. – Aleks G May 07 '13 at 09:43
  • Okay, I added the full stack trace. I hope that helps. @AleksG – Cheddar May 07 '13 at 20:53

2 Answers2

19

Reference

ContentValues values = new ContentValues();
            values.put(Data.RAW_CONTACT_ID, 001);
            values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
            values.put(Phone.NUMBER, "1-800-GOOG-411");
            values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
            values.put(Phone.LABEL, "Nirav");
            Uri dataUri = getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);

Use the above code. http://developer.android.com/reference/android/provider/ContactsContract.Data.html

Community
  • 1
  • 1
Nirav Ranpara
  • 13,753
  • 3
  • 39
  • 54
  • I tried your code, but the app still crashed. I then tried the code of the top answer in the first link you posted and the Toast caught an "Exception: Null." But I don't know what to make of that. – Cheddar May 07 '13 at 09:17
  • 1
    Have you permission of write contact ? – Nirav Ranpara May 07 '13 at 10:38
  • Yes, I have permissions to read and write, ``, ``, and I can already delete contacts (I do this by deleting from `RawContacts.CONTENT_URI`), so I don't think permissions are my problem. @NiravRanpara – Cheddar May 07 '13 at 20:54
  • 2
    I've marked the answer as correct because, while it didn't solve my problem, it was a proper response to what I asked for, an example of a contact being inserted to the contact's device. Clearly my problem isn't the way I am writing the actual insertion, but rather there is another issue that I am as yet unaware of. – Cheddar May 08 '13 at 05:37
  • It's not working in my case bro. This is my code: ContentValues values = new ContentValues(); values.put(Data.RAW_CONTACT_ID, mUserObj.getCardNumber()); values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); values.put(Phone.NUMBER, mUserObj.getPhoneNumber()); values.put(Phone.TYPE, Phone.TYPE_CUSTOM); values.put(Phone.LABEL, mUserObj.getFullName()); Uri dataUri = self.getContentResolver().insert(Data.CONTENT_URI, values); It does nothing. – Na Pro Dec 07 '17 at 03:45
1
ArrayList<ContentProviderOperation> ops =
      new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
      .withValue(Data.RAW_CONTACT_ID, rawContactId)
      .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
      .withValue(Phone.NUMBER, "1-800-GOOG-411")
      .withValue(Phone.TYPE, Phone.TYPE_CUSTOM)
      .withValue(Phone.LABEL, "free directory assistance")
      .build()); 
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
suresh
  • 123
  • 2
  • 6