问题
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>
回答1:
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();
}
}
}
}
}
回答2:
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);
来源:https://stackoverflow.com/questions/8006716/how-to-get-contacts-type-in-android