前面的文章已经实现相关的布局,本文接着进行相关的功能实现

本文地址:http://www.cnblogs.com/wuyudong/p/5951794.html,转载请注明出处。

读取系统联系人

当点击“选择联系人”按钮后,弹出联系人列表,读取系统联系人分如下几个步骤:

系统联系人提供了一个内容提供者,通过内容解析器,匹配Url地址

1,内容解析器

2,Url地址,查看系统联系人数据库,内容提供者源码

先看api文档的清单文件,后看java类(联系人数据库有多张表)

contents://com.android.contacts/表名

3,系统联系人数据库中核心表的表结构

raw_contacts 联系人表: contact_id 联系人唯一性id值

data 用户信息表:raw_contact_id作为外键,和raw_contacts中contact_id做关联查询

获取data1字段,包含了电话号码以及联系人名称

mimetype_id字段,包含了当前行data1对应的数据类型

mimetypes 类型表: 获取data表中mimetype_id和mimetypes中_id做关联查询,获取指向的信息类型
电话号码:vnd.android.cursor.item/phone_v2
用户名称:vnd.android.cursor.item/name

4,表的访问方式

content://com.android.contacts/raw_contacts
content://com.android.contacts/data

下面用代码实现

    private ListView lv_contact;
private List<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
private MyAdapter mAdapter; private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//8,填充数据适配器
mAdapter = new MyAdapter();
lv_contact.setAdapter(mAdapter);
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_list);
initUI();
initData();
} class MyAdapter extends BaseAdapter{ @Override
public int getCount() {
return contactList.size();
} @Override
public HashMap<String, String> getItem(int i) {
return contactList.get(i);
} @Override
public long getItemId(int i) {
return i;
} @Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = View.inflate(getApplicationContext(), R.layout.listview_contact_item, null);
TextView tv_name = (TextView)v.findViewById(R.id.tv_name);
TextView tv_phone = (TextView)v.findViewById(R.id.tv_phone);
tv_name.setText(getItem(i).get("name"));
tv_phone.setText(getItem(i).get("phone"));
return v;
}
} /**
* 获取联系人数据的方法
*/
private void initData() {
//因为读取系统联系人,可能是一个耗时操作,放置到子线程中处理
new Thread(){
public void run(){
//1,获取内容解析器对象
ContentResolver contentResolver = getContentResolver();
//2,做查询系统联系人数据库表过程(读取联系人权限)
Cursor cursor = contentResolver.query(
Uri.parse("content://com.android.contacts/raw_contacts"),
new String[]{"contact_id"},
null, null, null);
contactList.clear();
//3,循环游标,直到没有数据为止
while (cursor.moveToNext()){
String id = cursor.getString(0);
//4,根据用户唯一性id值,查询data表和mimetype表生成的视图,获取data以及mimetype字段
Cursor indexCursor = contentResolver.query(
Uri.parse("content://com.android.contacts/data"),
new String[]{"data1","mimetype"},
"raw_contact_id = ?", new String[]{id}, null);
//5,循环获取每一个联系人的电话号码以及姓名,数据类型
HashMap<String, String> hashMap = new HashMap<String, String>();
while (indexCursor.moveToNext()){
String data = indexCursor.getString(0);
String type = indexCursor.getString(1); //6,区分类型去给hashMap填充数据
if(type.equals("vnd.android.cursor.item/phone_v2")) {
//数据非空判断
if(!TextUtils.isEmpty(data)) {
hashMap.put("phone", data);
}
}else if(type.equals("vnd.android.cursor.item/name")) {
if(!TextUtils.isEmpty(data)) {
hashMap.put("name", data);
}
}
}
indexCursor.close();
contactList.add(hashMap); }
cursor.close();
//7,消息机制,发送一个空的消息,告知主线程可以去使用子线程已经填充好的数据集合
mHandler.sendEmptyMessage(0);
} }.start();
}

实现的效果如下:

联系人信息回显

接下来实现点击联系人条目,实现回显,例如双击第一个条目,号码自动添加

代码如下:

    private void initUI() {
lv_contact = (ListView) findViewById(R.id.lv_contact);
lv_contact.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//1,获取点中条目的索引指向集合中的对象
if(mAdapter != null) {
HashMap<String, String> hashMap = mAdapter.getItem(i);
//2,获取当前条目指向集合对应的电话号码
String phone = hashMap.get("phone");
//3,此电话号码需要给第三个导航界面使用 //4,在结束此界面回到前一个导航界面的时候,需要将数据返回过去
Intent intent = new Intent();
intent.putExtra("phone", phone);
setResult(0, intent);
finish(); }
}
});
}

接着onActivityResult中添加下面的代码

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(data != null) {
//1,返回到当前界面的时候,接受结果的方法
String phone = data.getStringExtra("phone");
//2,将特殊字符过滤(中划线转换成空字符串)
phone = phone.replace("-", "").replace(" ", "").trim();
et_phone_number.setText(phone); //3,存储联系人至sp中
SpUtil.putString(getApplicationContext(), ConstantValue.CONTACT_PHONE, phone);
}
super.onActivityResult(requestCode, resultCode, data);
}

当填写号码后,进入下一页,再次返回,发现号码不见了,于是使用sp存储并从中读取

    private void initUI() {
//显示电话号码的输入框
et_phone_number = (EditText)findViewById(R.id.et_phone_number);
//获取联系人电话号码回显过程
String contact_phone = SpUtil.getString(this, ConstantValue.CONTACT_PHONE, "");
et_phone_number.setText(contact_phone);
bt_select_number = (Button) findViewById(R.id.bt_select_number);
//点击选择联系人的对话框
bt_select_number.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), ContactListActivity.class);
startActivityForResult(intent, 0);
}
});
}

Android 手机卫士--获取联系人信息并显示与回显的更多相关文章

  1. [android] 手机卫士读取联系人

    获取ContentResolver内容解析器对象,通过getContentResolver()方法 调用ContentResolver对象的query()方法,得到raw_contacts表里面的数据 ...

  2. Android 手机卫士--设置界面&功能列表界面跳转逻辑处理

    在<Android 手机卫士--md5加密过程>中已经实现了加密类,这里接着实现手机防盗功能 本文地址:http://www.cnblogs.com/wuyudong/p/5941959. ...

  3. Android 手机卫士--确认密码对话框编写

    本文接着实现“确认密码”功能,也即是用户以前设置过密码,现在只需要输入确认密码 本文地址:http://www.cnblogs.com/wuyudong/p/5940718.html,转载请注明出处. ...

  4. Android 手机卫士--弹出对话框

    在<Android 手机卫士--解析json与消息机制发送不同类型消息>一文中,消息机制发送不同类型的信息还没有完全实现,在出现异常的时候,应该弹出吐司提示异常,代码如下: private ...

  5. android中ContentProvider获取联系人 总结

    35.内容提供者:ContentResolver 用内容提供者来获取联系人信息 35-1:权限 <!-- 对联系人的读.写权限 --> <uses-permission androi ...

  6. Android 手机卫士--参照文档编写选择器

    本文来实现<Android 手机卫士--导航界面1的布局编写>中的图片选择器部分的代码. 本文地址:http://www.cnblogs.com/wuyudong/p/5944356.ht ...

  7. Android 手机卫士--签名文件说明&包名说明

    在<Android 手机卫士--打包生成apk维护到服务器>一文中,实现了新版本的apk到服务器,当打开客户端apk的时候,发现有新版本,提示更新.还实现了利用xutils工具实现了从服务 ...

  8. Android 手机上获取手机当前上网IP地址

      [转] 原文              Android 手机上获取手机当前上网IP地址                (手机网关给手机号分配的IP) 每个手机上网通过移动网关的时候,网关都会给该手 ...

  9. android手机卫士、3D指南针、动画精选、仿bilibli客户端、身份证银行卡识别等源码

    Android精选源码 android身份证.银行卡号扫描源码 android仿bilibili客户端 android一款3D 指南针 源码 android手机卫士app源码 android提醒应用, ...

随机推荐

  1. 分布式唯一ID生成服务

    SNService是一款基于分布式的唯一ID生成服务,主要用于提供大数量业务数据建立唯一ID的需要;服务提供最低10K/s的唯一ID请求处理.如果你部署服务的CPU资源达到4核的情况下那该服务最低可以 ...

  2. deepsooncms在Ubuntu 14.04上部署教程

    deepsooncms在Ubuntu 14.04上部署教程 一.安装mono1.在命令行运行sudo apt-key adv --keyserver keyserver.ubuntu.com --re ...

  3. .NET Portability Analyzer 已开源

    在一年前介绍过<介绍.NET 开发必备工具 .NET Portability Analyzer>,微软已经把代码开源到Github:https://github.com/Microsoft ...

  4. Vue.js——基于$.ajax实现数据的跨域增删查改

    概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的.在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax ...

  5. Vue.js——60分钟组件快速入门(下篇)

    概述 上一篇我们重点介绍了组件的创建.注册和使用,熟练这几个步骤将有助于深入组件的开发.另外,在子组件中定义props,可以让父组件的数据传递下来,这就好比子组件告诉父组件:"嘿,老哥,我开 ...

  6. ucos实时操作系统学习笔记——任务间通信(队列)

    ucos操作系统中的queue机制同样使用了event机制来实现,其实和前面的sem,mutex实现类似,所不同的是对sem而言,任务想获得信号量,对mutex而言,任务想获得的是互斥锁.任务间通信的 ...

  7. C#将Word转换成PDF方法总结(基于Office和WPS两种方案)

    有时候,我们需要在线上预览word文档,当然我们可以用NPOI抽出Word中的文字和表格,然后显示到网页上面,但是这样会丢失掉Word中原有的格式和图片.一个比较好的办法就是将word转换成pdf,然 ...

  8. JavaScript dom 标签属性

    节点: 平时开发中常用的节点是: 元素节点:nodeType值是 1    --> <a>,<p>...... 属性节点:nodeType值是 2    --> t ...

  9. Dom addEventlistener与id 绑定事件的区别(续)

    addEventListener 第三个参数为 useCapture. 以一个例子说明. <div id="div1" style="background: blu ...

  10. Ios生产证书申请(含推送证书)

    一.Mac机上生成请求文件. Mac机上点击证书助手 => 从证书颁发机构请求证书 => 得到CertificateSigningRequest.certSigningRequest请求文 ...