0

I'm writing a function that will add Android contacts stored in my database to the user's contact list. I asked a similar question yesterday, Programmatically Inserting New Android Contacts into Phone, where I just asked for an example of inserting an Android contact to the contacts list. While I received a correct answer, it didn't solve the problem I was having. What my app does is take a contact that the user stored in my database, turns it into a contact object, and then takes information from the contact object and inserts it back into the phone. My issue is that the app crashes the second I try to insert any data to the device. Here's the code that I use up to the point of the crash:

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);
    values.clear();
}

I don't see any reason that wouldn't work, after all, I have the permissions to read and write contacts in the AndroidManifest.xml file:

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

Anyway, the person who responded to my last question provided the code,

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);

Running that, I still get the crash. Here's the logcat for that code the second I click the "Restore Contact" button in my app:

05-08 05:57:40.905: D/AndroidRuntime(2917): Shutting down VM
05-08 05:57:40.905: W/dalvikvm(2917): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-08 05:57:40.945: E/AndroidRuntime(2917): FATAL EXCEPTION: main
05-08 05:57:40.945: E/AndroidRuntime(2917): java.lang.NullPointerException
05-08 05:57:40.945: E/AndroidRuntime(2917):     at android.content.ContextWrapper.getContentResolver(ContextWrapper.java:99)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at com.protextyou.contacts.ContactHandler.addContact(ContactHandler.java:46)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at com.protextyou.StartPage$12.onClick(StartPage.java:542)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at android.os.Looper.loop(Looper.java:137)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at android.app.ActivityThread.main(ActivityThread.java:5041)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at java.lang.reflect.Method.invokeNative(Native Method)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at java.lang.reflect.Method.invoke(Method.java:511)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-08 05:57:40.945: E/AndroidRuntime(2917):     at dalvik.system.NativeStart.main(Native Method)

And of course, when I add a try/catch statement to the code, it comes up with "Exception: Null". So, I am guessing that NullPointerException is my issue, but I don't know what could be causing it. Could somebody explain what I might need to fix in order to make my app stop crashing?

Cheddar
  • 329
  • 2
  • 3
  • 9
  • Which one is Line:46 in your ContactHandler.java..??? – umair.ali May 08 '13 at 06:12
  • @umair.ali - Line 46 is `Uri dataUri = getContentResolver().insert(Data.CONTENT_URI, values);` – Cheddar May 08 '13 at 06:33
  • I don't think you need to specify contact_id or row_contact_id in case of insertion, because this _id field only allows unique values, and you insertion might duplicating it...I guess, you should not pass id in you query, then android will auto generate a new unique one. – umair.ali May 08 '13 at 06:50
  • @umair.ali - I commented out the `values.put("raw_contact_id", contact.getContactId());` line, as well as the line for lookup key for good measure, but the app still crashes. – Cheddar May 08 '13 at 07:06
  • Ok, are you making this db request on activity thread...??? Also tell me you Testing Android version... – umair.ali May 08 '13 at 07:25
  • @umair.ali - Er...database request on activity thread? I don't...think so? Are you talking about the `at android.app.ActivityThread.main(ActivityThread.java:5041)` in the logcat? What does that mean? As for the version, I'm targeting Android 2.3.3 (API level 10). – Cheddar May 08 '13 at 07:38
  • Hmmm...its not an issue than...also because you run some below code successfully, without crashing... – umair.ali May 08 '13 at 09:25
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29623/discussion-between-cheddar-and-umair-ali) – Cheddar May 09 '13 at 00:26

3 Answers3

0

This is the code that I am currently using to add contacts programatically.

import java.util.ArrayList;

import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Contacts.People;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.widget.Toast;

public class AddContactDemo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
addContact("Coderz","1234567890");
addContact("James","5656215521");
addContact("John","4545454545");
addContact("Mary","9632587410");
addContact("Peter","4561237890");
}
private void addContact(String name, String phone) {
ContentValues values = new ContentValues();
values.put(People.NUMBER, phone);
values.put(People.TYPE, Phone.TYPE_CUSTOM);
values.put(People.LABEL, name);
values.put(People.NAME, name);
Uri dataUri = getContentResolver().insert(People.CONTENT_URI, values);
Uri updateUri = Uri.withAppendedPath(dataUri, People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(People.Phones.TYPE, People.TYPE_MOBILE);
values.put(People.NUMBER, phone);
updateUri = getContentResolver().insert(updateUri, values);
}
}

You have already inserted permission to manifest, so I think you are good to go..

Hope this helps

CRUSADER
  • 5,486
  • 3
  • 28
  • 64
  • Unfortunately, this method gives me a crash with a logcat similar to the one I posted in my question. Also, the types `People` and `People.Phones` are deprecated, so I can't use them for this project. – Cheddar May 08 '13 at 06:40
  • Yes. Here is a screenshot of all the permissions I have, just for reference: http://gyazo.com/985463490a2b99518fa7e380f53a7b41.png – Cheddar May 08 '13 at 07:18
  • Well, I just gave you the code that we are currently using and it works great. I am working on what might be the issue in your case, but till then try this [as an alternative](http://stackoverflow.com/a/10276495/2345913) – CRUSADER May 08 '13 at 09:40
0

try to change the line values.put("contact_id", contact.getContactId()); to

values.put("raw_contact_id", contact.getContactId());

check it here http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html
and
http://developer.android.com/reference/android/provider/ContactsContract.DataColumns.html#RAW_CONTACT_ID

umesh
  • 1,148
  • 1
  • 12
  • 25
  • Doing that does make it so that the app doesn't crash, but there are two problems with this method: 1) the contact doesn't appear in the user's address book (for whatever reason) and 2) the contact ID I have is not the same as the raw contact ID, since there are multiple raw contact IDs per contact ID. However, this does help, since I now know I can user the insert function without my app crashing. – Cheddar May 08 '13 at 07:01
0

Check context variable in your addContact() method, probably it become null at the moment, you call that method. Your stacktrace clearly points to it.

Hope this helps.

Alexander Semenov
  • 1,513
  • 13
  • 20