3

I want to retrieve both contacts name and their type in my layout.I am providing my activities and layout file.I am getting an invalid column type exception.any help would be greatly appreciable.thanks in advance.

TestActivity.class:

        package application.test;
        import android.app.ListActivity;

        import android.os.Bundle;
        import android.provider.ContactsContract;
        import android.provider.ContactsContract.CommonDataKinds.Phone;
        import android.provider.ContactsContract.Data;
        import android.view.LayoutInflater;
        import android.view.ViewGroup.LayoutParams;
        import android.widget.LinearLayout;
        import android.widget.ListView;
        import android.widget.RelativeLayout;
        import android.content.ContentResolver;
        import android.database.Cursor;
        import android.database.SQLException;

        public class TestActivity extends ListActivity
        {
            String name[];
            String phoneType[];

            ListView lview; 
           ListViewAdapter lviewAdapter;
           @Override
            protected void onCreate(Bundle savedInstanceState) 
            {

                super.onCreate(savedInstanceState);       
                 LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);        
                LinearLayout mainLayout=new LinearLayout(this);
                mainLayout.setOrientation(LinearLayout.VERTICAL);               
                LayoutInflater layoutInflater = getLayoutInflater();        
                mainLayout.addView(layoutInflater.inflate(R.layout.main,null));
                mainLayout.addView(layoutInflater.inflate(R.layout.extra,null));

                this.addContentView(mainLayout, params);


              lview = (ListView) findViewById(android.R.id.list);
             getContacts(); 
          lviewAdapter=new ListViewAdapter(this, name, phoneType);
              lview.setAdapter(lviewAdapter);



             }//onCreate


           public void getContacts(){
               int i=0;
               ContentResolver cr = getContentResolver();

                         String[] projection = new String[] { Data._ID,
                      ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE}; 

              Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
                      projection, null, null, null); 



               if (cur != null && cur.moveToFirst()) { 

               try {

                    int indexID =  cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
                    int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
                    int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);

                 while (cur.moveToNext()) {

                    i++;
                     String id = cur.getString(indexID);    
                     name[i] = cur.getString(indexName);  
                     phoneType[i] =  cur.getString(indexPhoneType);
                 }

               } catch (SQLException sqle) {

              sqle.printStackTrace();
               } finally { 
                if (!cur.isClosed()) {
                    cur.close();
                }     
            }
           }
         }



        }

ListViewAdapter.class

        package application.test;
        import android.app.Activity;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        import android.widget.BaseAdapter;
        import android.widget.TextView;

        public class ListViewAdapter extends BaseAdapter  {

            Activity context;
            String name[];
            String phoneType[];

            public ListViewAdapter(Activity context,String[] name,String[] phoneType){
                super();
                this.context=context;
                   this.name=name;
                this.phoneType=phoneType;
            }




            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return name.length;
            }

            @Override
            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return 0;
            }
        public class viewHolder {
            TextView top;
            TextView bottom;
        }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub

                viewHolder holder;
                if(convertView==null){

                    LayoutInflater inflator=context.getLayoutInflater();
                convertView=inflator.inflate(R.layout.row,null);

                 holder=new viewHolder();
                holder.top=(TextView)convertView.findViewById(R.id.toptext);
                holder.bottom=(TextView)convertView.findViewById(R.id.bottomtext);
                convertView.setTag(holder);
                }else{
                    holder=(viewHolder)convertView.getTag();
                }

                holder.top.setText(name[position]);
                holder.bottom.setText(phoneType[position]);

                return convertView;
            }

 }         

row.xml:

          <?xml version="1.0" encoding="utf-8"?>
         <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="?android:attr/listPreferredItemHeight"
            android:padding="6dip">

            <LinearLayout
                android:orientation="vertical"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:layout_height="fill_parent">
                <TextView
                    android:id="@+id/toptext"
                    android:layout_width="fill_parent"
                    android:layout_height="0dip"
                    android:layout_weight="1"
                    android:gravity="center_vertical"
                />
                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="0dip"
                    android:layout_weight="1" 
                    android:id="@+id/bottomtext"
                    android:singleLine="true"
                    android:ellipsize="marquee"
                />
            </LinearLayout>
        </LinearLayout> 

main.xml:

          <?xml version="1.0" encoding="utf-8"?>

            <RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
            android:layout_width="fill_parent" android:id="@+id/relativeLayout1"
             android:layout_height="fill_parent">
                <TextView android:id="@+id/textView1"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_height="wrap_content" android:layout_width="wrap_content"
            android:text="All Contacts" android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"></TextView>
                <TextView android:id="@+id/textView2"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_height="wrap_content" android:layout_width="wrap_content"
            android:text="Search  " android:layout_alignBaseline="@+id/editText1"
            android:layout_alignBottom="@+id/editText1"
            android:layout_alignParentLeft="true"></TextView>
                <EditText android:layout_height="wrap_content" android:layout_width="180dp" android:id="@+id/editText1" android:layout_below="@+id/textView1" android:layout_toRightOf="@+id/textView2" android:layout_marginTop="18dp">
                    <requestFocus></requestFocus>
                </EditText>
                <Button android:layout_height="wrap_content"
            android:text="Search" android:layout_width="wrap_content" android:id="@+id/button_searchContact"
            android:layout_alignBottom="@+id/editText1" android:layout_toRightOf="@+id/editText1"></Button>
                <ListView android:id="@android:id/list"
            android:layout_height="wrap_content" android:layout_width="fill_parent"
            android:layout_marginBottom="70dp"
            android:layout_alignParentLeft="true" android:layout_below="@+id/editText1"></ListView>
            </RelativeLayout>

extra.xml:

        <?xml version="1.0" encoding="utf-8"?>

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical" android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:id="@+id/commonButtons"
            android:gravity="bottom">
            <ImageButton android:background="@drawable/favorite" android:layout_width="65dp" android:id="@+id/button_favorites" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="20dp"></ImageButton>
            <ImageButton android:background="@drawable/recents" android:layout_width="65dp" android:id="@+id/button_recent" android:layout_height="50dp" android:layout_alignTop="@+id/button_favorites" android:layout_toLeftOf="@+id/button_contacts"></ImageButton>
            <ImageButton android:background="@drawable/contacts" android:layout_width="65dp" android:id="@+id/button_contacts" android:layout_height="50dp" android:layout_alignTop="@+id/button_recent" android:layout_centerHorizontal="true"></ImageButton>
            <ImageButton android:background="@drawable/keypad" android:layout_width="65dp" android:id="@+id/button_keypad" android:layout_height="50dp" android:layout_alignTop="@+id/button_contacts" android:layout_toLeftOf="@+id/button_about"></ImageButton>
            <ImageButton android:background="@drawable/about" android:layout_width="65dp" android:id="@+id/button_about" android:layout_height="50dp" android:layout_alignTop="@+id/button_keypad" android:layout_alignParentRight="true"></ImageButton>
            <TextView android:layout_width="wrap_content" android:text="Favorites"
            android:id="@+id/textView1" android:layout_height="wrap_content"
            android:layout_below="@+id/button_recent" android:layout_toLeftOf="@+id/button_recent"></TextView>

        <TextView android:layout_width="wrap_content" android:text="Contacts"
            android:id="@+id/textView3" android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/textView2"
            android:layout_alignBottom="@+id/textView2" android:layout_toLeftOf="@+id/button_keypad" android:layout_alignLeft="@+id/button_contacts"></TextView>
        <TextView android:layout_width="wrap_content" android:text="  Recents" android:id="@+id/textView2" android:layout_height="wrap_content" android:layout_below="@+id/button_recent" android:layout_toRightOf="@+id/button_favorites" android:layout_alignRight="@+id/button_recent"></TextView>
        <TextView android:layout_width="wrap_content" android:text="  Keypad"
            android:id="@+id/textView4" android:layout_height="wrap_content"
            android:layout_alignParentBottom="true" android:layout_toRightOf="@+id/button_contacts"
            android:layout_toLeftOf="@+id/button_about"></TextView>
        <TextView android:layout_width="wrap_content" android:text="   About"
            android:id="@+id/textView5" android:layout_height="wrap_content"
            android:layout_alignParentBottom="true" android:layout_alignLeft="@+id/button_about"
            android:layout_alignParentRight="true"></TextView>
        </RelativeLayout>

AndroidManifest.xml:

        <?xml version="1.0" encoding="utf-8"?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="application.test"
              android:versionCode="1"
              android:versionName="1.0">
            <uses-sdk android:minSdkVersion="8"/>
             <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> 

            <application android:icon="@drawable/icon" android:label="@string/app_name">
                <activity android:name=".TestActivity"
                          android:label="@string/app_name">
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN" />
                        <category android:name="android.intent.category.LAUNCHER" />
                    </intent-filter>
                </activity>

            </application>
        </manifest>
Hiral Vadodaria
  • 19,158
  • 5
  • 39
  • 56

2 Answers2

2

Here's my Activity class I tested the code with. The layout is not important, as the contact info is printed on the standard output (look in DDMS).

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;  
import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public final class ContactManager extends Activity {

public static final String TAG = "ContactManager";
@Override
public void onCreate(Bundle savedInstanceState)
{
    Log.v(TAG, "Activity State: onCreate()");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contact_manager);

    testGetContacts();
}


private void testGetContacts() { 

        ContentResolver cr = getContentResolver();

        String[] projection = new String[] { Data._ID,
                ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE}; 

        Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
                projection, null, null, null); 


        if (cur != null && cur.moveToFirst()) { 

        try {

            int indexID =  cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
            int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
            int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);

          while (cur.moveToNext()) {
              String id = cur.getString(indexID);    
              String name = cur.getString(indexName);  
              String phoneType =  cur.getString(indexPhoneType);

              System.out.println(id + "\n");
              System.out.println(name + "\n");
              System.out.println(phoneType + "\n");
          }

        } catch (SQLException sqle) {
           //handle exception here - like missing column name!         
        } finally { //close your cursor if it's not needed!
         if (!cur.isClosed()) {
             cur.close();
         }     
     }
    }

}

}

hovanessyan
  • 30,580
  • 6
  • 55
  • 83
0

Suggestions for better code:

0) Add projection to your code => getting all columns is inefficient

    String[] projection = new String[] { ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.PhoneLookup.TYPE};

And than add the projection to your query:

Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
                        projection, null, null, null);

1) In your loop, your getting column index on every iteration. That's not necessary move the cur.getColumnIndex out of the loop.

2) When working with cursor, you may supplement the for-loop with while-condition loop. Here's a suggestion of impl. of your method getContacts():

  // A list of providers imports used!
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Contacts.Data;

 public void getContacts(){
         ContentResolver cr = getContentResolver();

                   String[] projection = new String[] { Data._ID,
                ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE}; 

        Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
                projection, null, null, null); 
         // don't use this ContentProvider
        // Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
                    //    projection, null, null, null);


         if (cur != null && cur.moveToFirst()) { 

         try {

              int indexID =  cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
              int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
              int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);

           while (cur.moveToNext()) {
            //do your logic here;           
              String id = cur.getString(indexID);    
              String name = cur.getString(indexName);  
              String phoneType =  cur.getString(indexPhoneType);
           }

         } catch (SQLException sqle) {
            //handle exception here - like missing column name!         
         } finally { //close your cursor if it's not needed!
          if (!cur.isClosed()) {
              cur.close();
          }     
      }
     }
   }

EDIT:

Use this imports:

 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Contacts.Data;

Use this projection

   String[] projection = new String[] { ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.PhoneLookup.TYPE};

Use this Query:

   Crsor cur = cr.query(ContactsContract.Data.CONTENT_URI,
                projection, null, null, null); 

Use this column names:

              int indexID =  cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
              int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
              int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);
hovanessyan
  • 30,580
  • 6
  • 55
  • 83
  • This is what I am getting after adding projection.(Exception has changed to invalid column type) .............................. – moderator_edited_name Nov 04 '11 at 09:56
  • try ContactsContract.Data.DISPLAY_NAME instead of ContactsContract.Contacts.DISPLAY_NAME. Which line throws the invalid column type? – hovanessyan Nov 04 '11 at 10:14
  • I tried debugging the code..here are the two cases.. 1]if I add projection column not found error is coming at [ Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);] 2]if I don't add projection then the (row0 col-1 failed) Exception is coming..any idea.. – moderator_edited_name Nov 04 '11 at 10:41
  • yeah - obviously the columns you're looking for are not all provided by this Content provider. In the first case, the query throws exception, as we're requesting a specific column, that does not exist. In the second case, the error comes when we try to get the index of a column, that does not exist. So it's the same issue. IDEA: comment the projection for now, execute and see on which line the getColumnIndexOrThrow is failing, so that we know which column is not provided. – hovanessyan Nov 04 '11 at 10:44
  • could you please provide the code for retrieving name and type of the contacts saved in phone and adding them to respective arrays..any help would be appreciable.. – moderator_edited_name Nov 04 '11 at 10:46
  • I just edited the code - there was an error - not retrieving indexes, but the data itself. I will test it now on my own. – hovanessyan Nov 04 '11 at 10:51
  • the problem is ContactsContract.PhoneLookup.TYPE – hovanessyan Nov 04 '11 at 10:57
  • Just fixed it in the code. As you can see, we retrieve now all the information and using projection. – hovanessyan Nov 04 '11 at 11:13
  • Do you get what you need to do after that in the while-loop? Create a simple POJO class, with fields that will hold the id, name, and phone type (if that's what you wanna carry), and use getters and setter to set the values. Something like viewHolder that you use. You can move that to it's own class. It's not needed to be inside ListViewAdapter. – hovanessyan Nov 04 '11 at 11:31
  • I replaced your getcontacts() with mine and again the same illegalargumentexception (column 'type' does not exist).. – moderator_edited_name Nov 04 '11 at 11:36
  • That's brutal...No wonder you will get it, as you're using the wrong Content Provider URI... – hovanessyan Nov 04 '11 at 11:38
  • what? nothing is working.Are my layouts are right.isn't it possible that I am dynamically adding layouts so may be that is creating the problem. – moderator_edited_name Nov 04 '11 at 12:04
  • Did the provided code fixed java.lang.illegalstateexception get field slot from row0 col-1 failed ? I can execute it on my environment successfully. – hovanessyan Nov 04 '11 at 12:06
  • yeah that is what I wrote.now column 'type ' does not exist coming. – moderator_edited_name Nov 04 '11 at 12:08
  • Have you used the imports, projection, query and column names I provided above, in the Edit, in your function getContacts()? – hovanessyan Nov 04 '11 at 12:11
  • yeah I have used them all.one exception which I also come across is 11-04 17:46:24.445: ERROR/dalvikvm(1326): Unable to open stack trace file '/data/anr/traces.txt': Permission denied – moderator_edited_name Nov 04 '11 at 12:19
  • do you have in your manifest ? Anyways, if you jump into other exceptions, I don't think they have to do anything with the above code. Good luck! – hovanessyan Nov 04 '11 at 12:21
  • yeah I have.and yeah thanks for the support.I owe you a big time. seems like I need some luck now. – moderator_edited_name Nov 04 '11 at 12:26
  • I made another application just to check the code and got difefrent exception this time..11-04 19:20:04.070: ERROR/AndroidRuntime(496): java.lang.RuntimeException: Unable to start activity ComponentInfo{application.test/application.test.TestActivity}: java.lang.NullPointerException – moderator_edited_name Nov 04 '11 at 13:51
  • I cannot really guess what's the reason, without code. FYI I have tested my code, and it works (in terms of getting the contacts info). I don't know what you try to do with it after that. – hovanessyan Nov 04 '11 at 13:55
  • I have pasted the whole code with two classes and three xml file and one manifest file – moderator_edited_name Nov 04 '11 at 14:17
  • I have added the link for the layout which I need along with the question – moderator_edited_name Nov 04 '11 at 14:22
  • I am not investing more time in this today. And now your question is hardly readable. – hovanessyan Nov 04 '11 at 14:25