Android简单获取手机联系人姓名电话号码

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;
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值