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

本文地址: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. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  2. Hyper-V上运行的Linux虚拟机验证是否安装了集成服务

    Hyper-V上运行的Linux虚拟机验证是否安装了集成服务 ps aux|grep "hv"root       311  0.0  0.0      0     0 ?     ...

  3. ASP.NET 5 Beta 7 版本

    在 VS2015 发布的同时,微软也发布了 ASP.NET 5 的路线图(详见ASP.NET 5 Schedule and Roadmap : https://github.com/aspnet/ho ...

  4. MapReduce剖析笔记之三:Job的Map/Reduce Task初始化

    上一节分析了Job由JobClient提交到JobTracker的流程,利用RPC机制,JobTracker接收到Job ID和Job所在HDFS的目录,够早了JobInProgress对象,丢入队列 ...

  5. CSharpGL(35)用ViewPort实现类似3DMax那样的把一个场景渲染到4个视口

    CSharpGL(35)用ViewPort实现类似3DMax那样的把一个场景渲染到4个视口 开始 像下面这样的四个视口的功能是很常用的,所以我花了几天时间在CSharpGL中集成了这个功能. 在CSh ...

  6. C#设计模式-策略者模式

    状态模式是对某个对象状态的抽象,而本文要介绍的策略模式也就是对策略进行抽象,策略的意思就是方法,所以也就是对方法的抽象,下面具体分享下我对策略模式的理解. 一. 策略者(Stragety)模式 在现实 ...

  7. ★Kali信息收集~ 1.Google Hacking + Github Hacking

    一.google hacking site site:cnblogs.com 毒逆天 intitle intitle:login allintitle allintitle:index of alli ...

  8. Android数据加密之Aes加密

    前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes ...

  9. c 线程(平行世界)

    我们已经知道如何使用进程来做一些事情了,然而 它并不是在什么地方都是最适合的. 我们看看进程的缺点是什么: 线程隆重登场 1. 如何创建线程 创建线程可以使用多种线程库,在此我们使用最流行的一种:PO ...

  10. JavaScript 函数节流和函数去抖应用场景辨析

    概述 也是好久没更新 源码解读,看着房价蹭蹭暴涨,心里也是五味杂陈,对未来充满恐惧和迷茫 ...(敢问一句你们上岸了吗) 言归正传,今天要介绍的是 underscore 中两个重要的方法,函数节流和函 ...