读取系统联系人
1、系统中联系人contacts的数据库保存在: /data/data/com.android.providers.contacts/databases/contacts2.db 2、查看源码,可以知道contacts的authorities(分号表示两个名字都可以) android:authorities="contacts;com.android.contacts" 3、查看源码,在ContactsProvider2.java中ctrl+F,输入UriMatcher。 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); 4、联系人中3个表主要字段之间的关系:
|
一、读取系统联系人(利用ContentProvider内容提供者) 1、先读取raw_contacts表,将联系人id(contact_id)给读取出来 2、再通过这个cursor,从表data,将数据给读取出来 注意:读取的不是data表,而是raw_contacts表和data表的视图,在data表中mimetype_id在该视图中为mimetype,而不是mimetype_id,否则会报错 3、将读取出来的每个联系人封装到一个javabean中去,再加入到List集合中 4、将List集合中的每一个联系人,用一个ListView给显示出来 步骤: 1、定义布局 a) 定义主界面
b) 定义ListView界面
2、创建内容提供者 3、写程序 |
二、核心代码 MainActivity.java
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import cn.zengfansheng.domain.ContactInfo;
import cn.zengfansheng.service.ContactInfoProvider;
public class MainActivity extends Activity {
private ListView lV;
private List<ContactInfo> allContacts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lV = (ListView) this.findViewById(R.id.lv_contacts);
}
/**
* 点击按钮获取全部系统联系人信息
*
* @param view
*/
public void getSysContacts(View view) {
allContacts = ContactInfoProvider.getAllContacts(this);
lV.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return allContacts.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(MainActivity.this, R.layout.list_contacts, null);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
TextView tv_email = (TextView) view.findViewById(R.id.tv_email);
TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);
ContactInfo contactInfo = allContacts.get(position);
tv_name.setText(contactInfo.getName());
tv_email.setText(contactInfo.getEmail());
tv_phone.setText(contactInfo.getPhone());
return view;
// return null;// 问题2:
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
}
-------------------------------------
ContactInfoProvider.java 内容提供者
import java.util.ArrayList;
import java.util.List;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import cn.zengfansheng.domain.ContactInfo;
public class ContactInfoProvider {
/**
* 获取系统全部联系人
*
* @param context
* @return
*/
public static List<ContactInfo> getAllContacts(Context context) {
List<ContactInfo> lInfos = new ArrayList<ContactInfo>();
// 1、从表raw_contacts中获取所有的联系人id(contact_id)
ContentResolver resolver = context.getContentResolver();
Uri contactUri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor contactcursor = resolver.query(contactUri, new String[] { "contact_id" }, null, null, null);
while (contactcursor.moveToNext()) {
String contactId = contactcursor.getString(0);// 0列是建立在参数二选择列表之上的
ContactInfo contactInfo = new ContactInfo();
if (contactId != null) { // 问题3:防止删除联系人,报异常
// 2、根据contactId从data表中获取数据
Cursor datacursor = resolver.query(dataUri, null, "raw_contact_id=?", new String[]{contactId}, null);
while (datacursor.moveToNext()) {
String data1 = datacursor.getString(datacursor.getColumnIndex("data1"));
String mimetype = datacursor.getString(datacursor.getColumnIndex("mimetype"));
// String mimetype = datacursor.getString(datacursor.getColumnIndex("mimetype_id"));
// 问题1:其实不是data表,是data表和raw_contacts表的视图,不是mimetype_id而是mimetype,可以通过下面的语句
/*String[] columnNames = datacursor.getColumnNames();
for (String string : columnNames) {
System.out.println(string);
}*/
if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {
contactInfo.setEmail(data1);
} else if ("vnd.android.cursor.item/name".equals(mimetype)) {
contactInfo.setName(data1);
} else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
contactInfo.setPhone(data1);
}
System.out.println("-------------------");
}
}
lInfos.add(contactInfo);
}
return lInfos;
} }结果:
|
问题1:权限 android.permission.READ_CONTACTS |
问题2:mimetype_id不存在,找的不是data表,其实是raw_contacts表和data表合并的视图,而该视图不存在mimetype_id,因为改了名字为mimetype, 技巧:判断列是什么名字,可以cursor.getColumnNames(),然后打印出来看下。 String[] columnNames = datacursor.getColumnNames();
for (String string : columnNames) {
System.out.println(string);
}
|
问题3:ListView中getView()方法返回view对象时,写得是null,报的空指针访问异常。特殊。
|
问题4:当删除联系人时,再开启程序,会报异常,这是因为android删除联系人时,不是将这条记录给删除, 而是将其置为了null,这主要是为了给同步到gmail方便,只要扫描那些为null,就删除,这是一个bug。
但还是占用一个格子。
|