Android简单获取手机联系人姓名电话号码
2016-04-08 19:56
525 查看
1.手机上联系人数据库文件(contact2.db)存放目录:/data/data/com.android.providers.contacts
2.联系人源码位于工程目录:packages\apps\Contacts
3.数据库中一堆表,但常用这些表:data、phone_lookup、contacts、raw_contacts
@ContactsDatabaseHelper.java
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'
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; } }
相关文章推荐
- Android 欢迎界面的实现(带透明度动画)
- android 关于触摸事件的理解
- Android studio开发中,利用日志查看当前的activity
- 人脸识别face++ SDK demo体验
- Android 学习记录-获取天气API
- 基于Android的一个简易计算器的实现
- 实用的Android代码片段集合(精)
- Android中文文档
- Android中文API文档
- Android Studio 编译问题(1)
- 关于android数据库no such table错误的反思
- Android自定义View,单点触控小球,自定义Imageview圆形图片
- android Actionmode 样式自定义
- android imageView释放内存
- Android中AIDL的实现使用
- Android 文字自动滚动(跑马灯)效果的两种实现方法
- Android Studio无法在线更新
- Android Studio安装后的一些必要设置
- android-22之HashMap学习
- Android中禁用屏幕旋转