8

I'm making an text message application and want to access contacts in my Android application .

I want to access contacts as if they where in the actual contact list. When selected I need to return to my activity in which I can send an SMS to that person. Or is it possible to access the database in which contacts are stored?

My code is shown below:

String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); 
String no = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));

My LogCat looks like this:

09-07 12:46:15.458: DEBUG/AndroidRuntime(473): Shutting down VM
09-07 12:46:15.458: WARN/dalvikvm(473): threadid=1: thread exiting with uncaught exception (group=0x40015560)
09-07 12:46:15.478: ERROR/AndroidRuntime(473): FATAL EXCEPTION: main
09-07 12:46:15.478: ERROR/AndroidRuntime(473): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/0r1-512D3F3D533B/1 flg=0x1 (has extras) }} to activity {task.list/task.list.Msgactivity}: java.lang.IllegalArgumentException: column 'data1' does not exist
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.access$2000(ActivityThread.java:117)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.os.Looper.loop(Looper.java:123)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.main(ActivityThread.java:3683)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at java.lang.reflect.Method.invokeNative(Native Method)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at java.lang.reflect.Method.invoke(Method.java:507)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at dalvik.system.NativeStart.main(Native Method)
09-07 12:46:15.478: ERROR/AndroidRuntime(473): Caused by: java.lang.IllegalArgumentException: column 'data1' does not exist
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at task.list.Msgactivity.onActivityResult(Msgactivity.java:99)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.Activity.dispatchActivityResult(Activity.java:3908)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
09-07 12:46:15.478: ERROR/AndroidRuntime(473):     ... 11 more
09-07 12:46:15.489: WARN/ActivityManager(61):   Force finishing activity task.list/.Msgactivity

Can anyone help me?

Jasper
  • 2,166
  • 4
  • 30
  • 50
sajith
  • 2,564
  • 8
  • 39
  • 57

4 Answers4

15

use this code to pick contact:

 Button button = (Button)findViewById(R.id.pickcontact);

    button.setOnClickListener(new OnClickListener() 
        {
            @Override
            public void onClick(View v) 
            {
                 Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                 startActivityForResult(intent, PICK_CONTACT);
             }
         });



    @Override public void onActivityResult(int reqCode, int resultCode, Intent data){ super.onActivityResult(reqCode, resultCode, data);

    switch(reqCode)
    {
       case (PICK_CONTACT):
         if (resultCode == Activity.RESULT_OK)
         {
             Uri contactData = data.getData();
             Cursor c = managedQuery(contactData, null, null, null, null);
          if (c.moveToFirst())
          {
          String id = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));

          String hasPhone =
          c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

          if (hasPhone.equalsIgnoreCase("1")) 
          {
         Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
          ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
            phones.moveToFirst();
            String cNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
           // Toast.makeText(getApplicationContext(), cNumber, Toast.LENGTH_SHORT).show();
            setCn(cNumber);
          }
         }
       }
    }
   }
kgandroid
  • 5,507
  • 5
  • 39
  • 69
sawan
  • 2,341
  • 3
  • 25
  • 51
  • thank you but how can i store the selected contact number to a variable – sajith Sep 07 '11 at 07:27
  • What happen if there are more than one number to the selected ID. According above code, this retrieve the first number. Isn't there any option for user to choose which number he wants? – AnujAroshA Apr 03 '12 at 09:48
2

try this code. this stores all the contacts in the ArrayList

ArrayList<HashMap<String,String>> contactData=new ArrayList<HashMap<String,String>>();
ContentResolver cr = getContentResolver();
 Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
 while (cursor.moveToNext()) {
     try{
     String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
     String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
     String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); 
     if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
         Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
         while (phones.moveToNext()) { 
             String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER));
             HashMap<String,String> map=new HashMap<String,String>();
             map.put("name", name);
             map.put("number", phoneNumber);
             contactData.add(map);
         } 
         phones.close(); 
     }
 }catch(Exception e){}
 }

if you want to store the specific contact use the if condition.

Balaji.K
  • 8,745
  • 5
  • 30
  • 39
  • hasPhone returns value 1,but an error occurs when String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER)); executes,what will be the problem – sajith Sep 07 '11 at 08:38
  • what it means "hasPhone returns value 1". not getting ur problem – Balaji.K Sep 07 '11 at 09:17
  • String hasPhone =c.getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); – sajith Sep 13 '11 at 03:11
0

I was able to use @Balaji.K 's example with some modification. The main issue I ran into is that

while (cursor.moveToNext()) {

will skip over the first result.

I also wanted to build a list of phone numbers for a user to select from if none are marked as "Mobile". I also pass in a name to search (variable replaced with in this example), but one could modify this code to build a collection by replacing "selection" and "selection_args" with null and iterating over everything in "contacts" as I did for "phones". Here is what I ended up with (in Kotlin):

val selection = "lower(${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY}) LIKE ?"
val selectionArgs = arrayOf("<SEARCH_TERM>")
selectionArgs[0] = "%<SEARCH_TERM>%"

// Query contacts for someone with a matching name
val contacts = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,
        null, selection, selectionArgs, null)
contacts!!.moveToFirst()
if (contacts.count > 1) {
    // TODO: Disambiguate and move to the correct position
}
val contactId = contacts.getString(contacts.getColumnIndex(
        ContactsContract.Contacts._ID))

// Check if contact has at least one phone number
if (contacts.getString(contacts.getColumnIndex(
                ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER)) == "1") {

    val sel = "${ContactsContract.CommonDataKinds.Email.CONTACT_ID} = ?"
    val selArgs = arrayOf(name)
    val sort = "${ContactsContract.CommonDataKinds.Email.LAST_TIME_CONTACTED} DESC"
    selArgs[0] = contactId

    val phones = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, sel, selArgs, sort)
    phones!!.moveToFirst()

    // Iterate through phone numbers if multiple
    if (phones.count > 1) {
        val phoneNumbers = mutableMapOf<Int, ContactData>()
        var loop = true
        var mobileIndex: Int? = null
        while (loop) {
            val phoneType = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE))
            val phoneName = ContactsContract.CommonDataKinds.Phone.getTypeLabel(resources, phoneType, null).toString()
            phoneNumbers[phones.position] = ContactData(phoneName, phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)))
            // Remember what position the mobile number was in
            if (phoneType == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
                mobileIndex = phones.position
            }
            loop = phones.moveToNext()
        }
        phones.moveToPosition(mobileIndex)
    }
}