1.手机上联系人数据库文件(contact2.db)存放目录:/data/data/com.android.providers.contacts
2.联系人源码位于工程目录:packages\apps\Contacts
3.数据库中一堆表,但常用这些表:data、phone_lookup、contacts、raw_contacts
@ContactsDatabaseHelper.java
public interface Tables {
public static final String CONTACTS = "contacts";
public static final String DELETED_CONTACTS = "deleted_contacts";
public static final String RAW_CONTACTS = "raw_contacts";
public static final String STREAM_ITEMS = "stream_items";
public static final String STREAM_ITEM_PHOTOS = "stream_item_photos";
public static final String PHOTO_FILES = "photo_files";
public static final String PACKAGES = "packages";
public static final String MIMETYPES = "mimetypes";
public static final String PHONE_LOOKUP = "phone_lookup";
public static final String NAME_LOOKUP = "name_lookup";
public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions";
public static final String SETTINGS = "settings";
public static final String DATA = "data";
public static final String GROUPS = "groups";
public static final String PRESENCE = "presence";
public static final String AGGREGATED_PRESENCE = "agg_presence";
public static final String NICKNAME_LOOKUP = "nickname_lookup";
public static final String CALLS = "calls";
public static final String CALLS_SYNC = "calls_sync";
public static final String STATUS_UPDATES = "status_updates";
public static final String PROPERTIES = "properties";
public static final String ACCOUNTS = "accounts";
public static final String VISIBLE_CONTACTS = "visible_contacts";
public static final String DIRECTORIES = "directories";
public static final String DEFAULT_DIRECTORY = "default_directory";
public static final String SEARCH_INDEX = "search_index";
public static final String VOICEMAIL_STATUS = "voicemail_status";
//add by lumos
public static final String GROUP_LOOKUP = "group_lookup";
public static final String SPAM_ADDRESS = "spam_address";
public static final String SPEED_DIAL = "speed_dial";
// This list of tables contains auto-incremented sequences.
public static final String[] SEQUENCE_TABLES = new String[] {
CONTACTS,
RAW_CONTACTS,
STREAM_ITEMS,
STREAM_ITEM_PHOTOS,
PHOTO_FILES,
DATA,
GROUPS,
CALLS,
DIRECTORIES
};
4.查询时使用Phone.CONTENT_URI会关联查询多张表(contacts、raw_contacts、data?详情查看源码ContactsProvider2.java) ,返回的结果中已经包含了很多信息,如联系人姓名、电话号码等,基本可以满足一般需求
@ContactsProvider2.java
matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES)
5.代码实现(异步加载使用rxjava)
权限申请:<uses-permission android:name="android.permission.READ_CONTACTS"/>
远程库依赖: compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
package com.example.lance.contactdbtest;
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class MainActivity extends ListActivity {
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
adapter = new MyAdapter();
getListView().setAdapter(adapter);
Observable.create(new Observable.OnSubscribe<List<Contact>>() {
@Override
public void call(Subscriber<? super List<Contact>> subscriber) {
try {
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null);
if(cursor != null){
int nameId = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY);
int numberId = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
List<Contact> contacts = new ArrayList<Contact>();
while (cursor.moveToNext()){
Contact contact = new Contact();
contact.name = cursor.getString(nameId);
contact.number = cursor.getString(numberId);
contacts.add(contact);
}
subscriber.onNext(contacts);
subscriber.onCompleted();
}
} catch (Exception e) {
if (subscriber.isUnsubscribed()) {
//refuse to emit onError if already unsubscribed
return;
}
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Contact>>() {
@Override
public void onCompleted() {
Log.i("test", "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.e("test", "onError");
e.printStackTrace();
}
@Override
public void onNext(List<Contact> contacts) {
adapter.addAll(contacts);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class MyAdapter extends BaseAdapter {
List<Contact> mContacts = new ArrayList<>();
public void addAll(List<Contact> contacts){
mContacts.addAll(contacts);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mContacts.size();
}
@Override
public Object getItem(int i) {
return i;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View holder = view;
if(holder == null){
holder = getLayoutInflater().inflate(R.layout.list_item, viewGroup, false);
}
Contact contact = mContacts.get(i);
if(contact != null) {
((TextView) holder.findViewById(R.id.name)).setText(contact.name);
((TextView) holder.findViewById(R.id.number)).setText(contact.number);
}
return holder;
}
}
class Contact{
String name;
String number;
}
}