ListAdapter adapter = new SimpleCursorAdapter(this,
//定义List中每一行的显示模板
//表示每一行包含两个数据项
android.R.layout.simple_list_item_2,
//数据库的Cursor对象
cursor,
//从数据库的Name额Number两列中取数据
new String [] {PhoneLookup.DISPLAY_NAME,PhoneLookup.NUMBER},
//与name和number对应的views
new int[] {android.R.id.text1,android.R.id.text2});
把PhoneLookup.NUMBER和android.R.id.text2删除之后就可用了
或者把NUMBER换成其他参数也可以,为什么会这样
加权限没?没看到你做查询的操作?
Cursor cursor = null;
try {
// 查询联系人数据
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
// 获取联系人姓名
String displayName = cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
// 获取联系人手机号
String number = cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
contactsList.add(displayName + "\n" + number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
参考一下吧
提示你一个完整的例子,看看吧。
@SuppressWarnings("deprecation")
public class PhoneBookActivity extends ActionBarActivity {
private ListView lvContacts = null;
List<phoneBookInfo> contacts = null;
boolean snapAlready = false;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_book);
// 去掉 Activity 上面的状态栏(系统)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide();
findViews();
if(!snapAlready){
snapAlready = true;
MainActivity.SnapCurrentViewToFile(getApplicationContext(),lvContacts);
}
contacts = getContactsInfoList2(getApplicationContext());
String strName = null;
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
for (Iterator<phoneBookInfo> iterator = contacts.iterator(); iterator.hasNext();) {
phoneBookInfo oneContact = (phoneBookInfo)iterator.next();
Log.i("Phone Link", "number of contact is: " + oneContact.getNumber(0));
strName = oneContact.getName();
HashMap<String, String> map = new HashMap<String, String>();
if(null == strName) {
map.put("ItemRecordName", oneContact.getNumber(0));
map.put("ItemRecordText", null);
}
else {
if(strName.isEmpty()) {
map.put("ItemRecordName", oneContact.getNumber(0));
map.put("ItemRecordText", null);
}
else {
map.put("ItemRecordName", strName);
map.put("ItemRecordText", oneContact.getNumber(0));
}
}
mylist.add(map);
}
// 生成 Apapter(适配器), 数组 -> ListItem
SimpleAdapter mSchedule = new SimpleAdapter(this,
// 数据来源
mylist,
// ListItem 的XML实现
R.layout.my_filelistformat,
// 动态数组与 ListItem 对应的子项
new String[] {"ItemRecordName", "ItemRecordText"},
// ListItem 的 XML 文件里面的两个 TextView ID
new int[] {R.id.ItemRecordName,R.id.ItemRecordText});
lvContacts.setAdapter(mSchedule);
Intent commonCtrl_intent = new Intent();
commonCtrl_intent.setAction(AppConstant.COMMON_UI_MSG);
commonCtrl_intent.putExtra("ACTION", "UIIndex");
commonCtrl_intent.putExtra("index", 3);
sendBroadcast(commonCtrl_intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.phone_book, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onStart(){
super.onStart();
// Intent commonCtrl_intent = new Intent();
// commonCtrl_intent.setAction(AppConstant.COMMON_UI_MSG);
// commonCtrl_intent.putExtra("ACTION", "UIIndex");
// commonCtrl_intent.putExtra("index", 3);
// sendBroadcast(commonCtrl_intent);
if(!snapAlready){
snapAlready = true;
MainActivity.SnapCurrentViewToFile(getApplicationContext(),lvContacts);
}
}
@Override
public void onStop(){
super.onStop();
snapAlready = false;
}
private void findViews() {
lvContacts = (ListView)findViewById(R.id.listView1);
lvContacts.setOnItemClickListener(new ContactListItemClickListener());
}
private class ContactListItemClickListener implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
// TODO Auto-generated method stub
if(contacts != null)
{
phoneBookInfo selRecord = contacts.get(position);
Intent commonCtrl_intent = new Intent();
commonCtrl_intent.setAction(AppConstant.COMMON_UI_MSG);
commonCtrl_intent.putExtra("ACTION", "UIDial");
if(null == selRecord.getName()) {
commonCtrl_intent.putExtra("number", selRecord.getNumber(0));
}
else {
commonCtrl_intent.putExtra("number", selRecord.getName() + "(" + selRecord.getNumber(0) + ")");
}
sendBroadcast(commonCtrl_intent);
Uri dialUrl = Uri.parse("tel:" + selRecord.getNumber(0));
Intent dialIntent = new Intent(Intent.ACTION_CALL,dialUrl);
startActivity(dialIntent);
}
}
}
/* 读取手机中的 Contacts 内容 : 适用于 Android 1.5 及以上版本(含2.X,3.X)*/
public static List<phoneBookInfo> getContactsInfoList(Context context) {
/* 取得 ContentResolver */
ContentResolver cr = context.getContentResolver();
/* 取得通讯录的 Phones 表的 cursor */
Cursor cursor = cr.query(Contacts.Phones.CONTENT_URI,
null,null, null, Contacts.People.DEFAULT_SORT_ORDER); // Contacts.People.DISPLAY_NAME + " COLLATE LOCALIZED ASC"
/* Log 输出列名 */
for (int i = 0; i < cursor.getColumnCount(); i++) {
String columnName = cursor.getColumnName(i);
Log.d("Phone Link","read contacts No." + Integer.toString(i + 1) + " column strName is: " + columnName);
}
/* 逐条读取记录信息 */
int sum = cursor.getCount();
List<phoneBookInfo> phoneBooks = new ArrayList<phoneBookInfo>();
Log.v("Phone Link", "read contacts sum = " + sum); // Leo 20141216 会将有多个电话号码的条目拆分为多条供查询,其 Person ID 是相同的
for (int i = 0; i < sum; i++) {
cursor.moveToPosition(i);
phoneBookInfo oneBook = new phoneBookInfo();
oneBook.setPersionId(cursor.getString(cursor.getColumnIndexOrThrow(Contacts.Phones.PERSON_ID)));
oneBook.setName(cursor.getString(cursor.getColumnIndexOrThrow(Contacts.Phones.NAME)));
// 读取号码与号码类型
oneBook.setType(cursor.getString(cursor.getColumnIndexOrThrow(Contacts.Phones.TYPE)));
oneBook.setNumber(cursor.getString(cursor.getColumnIndexOrThrow(Contacts.Phones.NUMBER)));
oneBook.setNumber((null == oneBook.getNumber(0)) ? "无号码" : oneBook.getNumber(0));
// 读取号码与号码类型方法2: 但读取的号码有问题
/*int idColumn = cursor.getColumnIndex(Contacts.People._ID);
String contactId = cursor.getString(idColumn);
//获取联系人的电话号码
Cursor phonesCur = context.getContentResolver().query(
Contacts.Phones.CONTENT_URI,null,Contacts.Phones.PERSON_ID+ "=" + contactId, null, null);
if(phonesCur.moveToFirst()) { // 有多个号码的通讯录条目在此处读取得到的号码为空 ???
do{
// 遍历所有的电话号码
String phoneType = phonesCur.getString(phonesCur
.getColumnIndex(Contacts.PhonesColumns.TYPE));
String phoneNumber =phonesCur.getString(phonesCur
.getColumnIndex(Contacts.PhonesColumns.NUMBER));
// 自己的逻辑处理代码
Log.i("Phone Link", "read contacts: " + phoneType + " " + phoneNumber);
oneBook.setType(phoneType);
oneBook.setNumber(phoneNumber);
}while(phonesCur.moveToNext());
}*/
phoneBooks.add(oneBook);
Log.v("Phone Link", "read contacts strPersionID = " + oneBook.getPersionId());
Log.v("Phone Link", "read contacts strType = " + oneBook.getType(0));
Log.v("Phone Link", "read contacts strName = " + oneBook.getName());
Log.v("Phone Link", "read contacts strNumber = " + oneBook.getNumber(0));
}
cursor.close();
return phoneBooks;
}
/* 适用于 Android 2.0 及以上版本的读取通讯录的代码 */
public static List<phoneBookInfo> getContactsInfoList2(Context context) {
List<phoneBookInfo> phoneBooks = new ArrayList<phoneBookInfo>();
// 读取手机本地的电话
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
// 取得电话本中开始一项的光标,必须先 moveToNext()
while(cursor.moveToNext()) {
phoneBookInfo oneBook = new phoneBookInfo();
// 取得联系人的名字索引
String name = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME)); // ContactsContract.Contacts.DISPLAY_NAME
Log.i("Phone Link", "phone name: " + name);
String isHasPhoneNumber = cursor.getString(cursor.getColumnIndex(PhoneLookup.HAS_PHONE_NUMBER));
// 取得联系人的 ID 索引值
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
oneBook.setName(name);
// 查询该位联系人的电话号码,类似的可以查询 E-Mail,photo
if(isHasPhoneNumber.equalsIgnoreCase("1")) {
// 第一个参数是确定查询电话号,第三个参数是查询具体某个人的过滤值
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
// 一个人可能有几个号码
while(phone.moveToNext()){
String phoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String phoneType = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Phone Link", "phone number: " + phoneNumber + " Type: " + phoneType);
oneBook.setType(phoneType);
oneBook.setNumber(phoneNumber);
}
phone.close();
}
else {
oneBook.setNumber("无号码");
}
Cursor email = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);
while(email.moveToNext()) {
String emailAddr = email.getString(email.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
String emailType = email.getString(email.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
Log.i("Phone Link", "E-Mail address: " + emailAddr + " Type: " + emailType);
oneBook.setEMail(emailAddr);
oneBook.setEMailType(emailType);
}
email.close();
// 联系人的地址信息
Cursor sp = cr.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null,
ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + contactId, null, null);
while(sp.moveToNext()) {
String structPostal = sp.getString(sp.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA));
Log.i("Phone Link", "Structured Postal: " + structPostal);
}
phoneBooks.add(oneBook);
sp.close();
}
cursor.close();
return phoneBooks;
}
}