Reputation: 41
I want to display the contact name and it's phone number in a check box in this manner: "ContactName : Phone number"
But I find this error in the logcat "java.lang.IllegalArgumentException: Invalid column data1"
Here is the code I work with ----->
package wael.ilahi.pfe;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.zip.Inflater;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
...
public class SelectFriends extends Activity implements OnClickListener {
public static final String TAG = "ContactManager";
private Button bSave;
private ListView lv;
private boolean mShowInvisible;
CheckBox ch;
String s;
int k=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.v(TAG, "Activity State: onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
bSave = (Button) findViewById(R.id.addContactButton);
lv = (ListView) findViewById(R.id.contactList);
populateContactList();
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,final
int position, long id) {
ch = (CheckBox) view.findViewById(R.id.checkBox);
ch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
"Click ListItem Number " + position, Toast.LENGTH_LONG).show();
}
});
}
});
bSave.setOnClickListener(this);
}
private void populateContactList() {
// Build adapter with contact entries
Cursor cursor = getContacts();
String[] fields = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +":"+
ContactsContract.CommonDataKinds.Phone.NUMBER};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.contact_entry, cursor,fields, new int[] {R.id.checkBox});
lv.setAdapter(adapter);
}
private Cursor getContacts(){
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
//ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER };
String selection = null;
String[] selectionArgs = null;
String sortOrder =null;
return managedQuery(uri, projection, selection, selectionArgs, sortOrder);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
Upvotes: 0
Views: 700
Reputation: 8641
It looks like your trying to query the Contacts table and return a phone number from it.
Unfortunately, that's not how the Contacts Provider works. In summary: The Contacts Provider has three tables: Contacts, RawContacts, and Data. Each Contact row points to one or more RawContacts rows. Each RawContact row points to one or more Data rows.
People are stored into the Contacts Provider as raw contacts. The provider itself creates Contact rows. One raw contact name is chosen automatically as the DISPLAY_NAME_PRIMARY of the Contact row.
The Data table contains the details for a raw contact. The rows are generic. Every one of them has the same column names, which you can see in ContactsContract.Data. To choose a particular type of detail, such as a phone number, you have to search for the Data row that has a MIME type of ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE. You can then refer to the phone number in that row as ContactsContract.CommonDataKinds.Phone.PHONE_NUMBER; the value of this constant is "data1". That is, constants in the CommonDataKinds classes are aliases to the column names DATA1-DATA15 defined in ContactsContract.Data. The aliases make it easier to understand the semantics of a Data row.
There's a simple way to accomplish your goal: use the ContactsContract.Contacts.Entity construct. This returns a Cursor containing all the Data and RawContacts rows for a Contact. If you set your selection arguments to ContactsContract.Data.MIME_TYPE = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, you'll only retrieve phone numbers.
Notes: A raw contact's display name is stored in the Data table, as a ContactsContract.CommonDataKinds.StructuredName row.
Upvotes: 1