как получить тип контактов в Android?

#android #android-contacts

#Android #android-контакты

Вопрос:

Я хочу получить как имя контактов, так и их тип в моем макете.Я предоставляю свои действия и файл макета.Я получаю недопустимое исключение типа столбца.любая помощь была бы весьма ощутимой.заранее спасибо.

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

Комментарии:

1. Иисус, опубликуй свой полный код. Вы перемещаете курсор на первый элемент? Где ваша ПРОЕКЦИЯ?

Ответ №1:

Вот мой класс активности, с которым я тестировал код. Макет не важен, так как контактная информация печатается на стандартном выводе (посмотрите в 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 amp;amp; 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();
         }     
     }
    }

}
  

}

Ответ №2:

Предложения по улучшению кода:

0) Добавьте проекцию в свой код => получение всех столбцов неэффективно

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

И затем добавьте проекцию в свой запрос:

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

1) В вашем цикле вы получаете индекс столбца на каждой итерации. В этом нет необходимости выводить cur.getColumnIndex из цикла.

2) При работе с курсором вы можете дополнить цикл for циклом while-condition. Вот предложение impl. вашего метода 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 amp;amp; 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();
          }     
      }
     }
   }
  

Редактировать:

Используйте этот импорт:

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

Используйте эту проекцию

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

Используйте этот запрос:

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

Используйте имена столбцов:

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

Комментарии:

1. Это то, что я получаю после добавления проекции. (Исключение изменено на недопустимый тип столбца)…………………………

2. попробуйте ContactsContract.Data.DISPLAY_NAME вместо ContactsContract. Контакты. ИМЯ_СООБЩЕНИЯ. Какая строка выдает недопустимый тип столбца?

3. Я попытался отладить код .. вот два случая .. 1] если я добавлю столбец проекции не найден, появится ошибка [Cursor cur = cr.query(ContactsContract. Контакты. CONTENT_URI, проекция, нуль, null, null);] 2] если я не добавлю проекцию, то появится исключение (ошибка row0 col-1) .. есть идеи..

4. да — очевидно, что не все столбцы, которые вы ищете, предоставлены этим поставщиком контента. В первом случае запрос выдает исключение, поскольку мы запрашиваем определенный столбец, который не существует. Во втором случае ошибка возникает, когда мы пытаемся получить индекс столбца, который не существует. Итак, это та же проблема. ИДЕЯ: прокомментируйте проекцию на данный момент, выполните и посмотрите, в какой строке происходит сбой getColumnIndexOrThrow, чтобы мы знали, какой столбец не указан.

5. не могли бы вы предоставить код для получения имени и типа контактов, сохраненных в телефоне, и добавления их в соответствующие массивы .. любая помощь была бы заметна..