解剖Android联系人之二,基于2.1

本文详细介绍了如何通过Android API读取联系人数据,包括姓名、电话号码、电子邮件等信息,并探讨了联系人数据表之间的关联及版本控制的方法。
上次把联系人的表都打开看了看,也了解了些东西

现在要开始编程了

要从联系人当中提取哪些信息呢?

ID 看起来没用的数据
显示的名字


(中间名可以省咯了,中国人基本用不到)
电话
更多电话(家里,工作,等等)
电子邮件(家里,工作,等等)
即时通信(QQ,MSN,Skype,Gtalk,等等)
通讯地址
昵称
备注
网站
更重要的一个东西就是数据的版本号,就是上次我们看到很高兴的那个字段version
data表中有个version字段,raw_contacts表中有个version字段,contacts表中没有

这样只需要我们构建一张表来记录相关数据,我们就能知道哪些数据是在某个时间点后变化过的
如果牛逼的话,就HACK联系人的数据库,给它加个触发器来更改我们表的数据,当然我们的表得放在联系人的数据库当中,又不能像Oracle样建个DATABASE LINK,但是这基本是不可能的

扯远了

现在我们首要任务是在API中把那些对应的字段找出来,把数据读出来
上次我们在分析表的时候发现对于id有很多引用,比如raw_contacts中的contact_id就引用了contacts中的id,并且data中的raw_contact_id又引用了raw_contacts中的_id,这其实还是个比较重要的信息
我们就可以知道,在所有的数据当中,contacts是最开始的,它是起源,虽然它本身不带有很多数据,但是他的作用不可忽视

所以
ID <----------> ContactsContract.Contacts._ID
看看ContactsContract.Contacts._ID的注释我们也可以理解,The unique ID for a row. INTEGER (long)

显示的名字 <----------> ContactsContract.Contacts.DISPLAY_NAME

名 <----------> ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME
姓 <----------> ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME

看了下表的数据,data表中有条数据是
9||9|1|0|0|0|海 郭|海|郭||||||||||||||||

第三列对应于mimetype,查下mimetype表之后9对应于vnd.android.cursor.item/name
那么我们只需要根据ID和类型查询出这条数据,然后再取出第九列和第十列的数据就应该OK了,第八列是显示的名字
即DATA2(名)和DATA3(姓)
SDK已经帮我们封装好了就是ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME和ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME

那么读出联系人数据的代码就应该可以是如下这个样子的
private List showContacts() {
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
while (cursor.moveToNext()) {
String contactId = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));

String dn = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.v("DISPLAY NAME", dn);

// ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYP,表示是姓名系
Cursor names = getContentResolver()
.query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID
+ " = ? AND "
+ ContactsContract.Data.MIMETYPE
+ " = ?",
new String[] {
contactId,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE },
null);
// + " AND " + ContactsContract.Data.MIMETYPE + " = 9"
// 非要这么写才出来,用什么数值,或者StructuredName不放在selectionArgs都出不来,想知道它是如何拼写SQL的?

while (names.moveToNext()) {
// 名
String gn = names
.getString(names
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
Log.v("GIVEN NAME", gn);
// 姓
String fn = names
.getString(names
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
Log.v("FAMILY NAME", fn);
// 姓名数据版本
String versions = names
.getString(names
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DATA_VERSION));
Log.v("DATA VERSION", versions);
}
names.close();

// 查询RawContacts,这个里面有版本号version,关键字段

Cursor raws = getContentResolver()
.query(
ContactsContract.RawContacts.CONTENT_URI,
null,
ContactsContract.RawContacts.CONTACT_ID
+ " = ?",
new String[] { contactId, },
null);

while (raws.moveToNext()) {
String rawVersion = raws
.getString(raws
.getColumnIndex(ContactsContract.RawContacts.VERSION));
Log.v("RAW VERSION", rawVersion);
}
raws.close();

String hasPhone = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if ("1".equals(hasPhone)) {
Cursor phones = getContentResolver()
.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = "
+ contactId,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.v("phone", phoneNumber);
}
phones.close();
}
Cursor emails = getContentResolver()
.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = "
+ contactId,
null, null);
while (emails.moveToNext()) {
String emailAddress = emails
.getString(emails
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); // 如何获取Email地址
// 为什么ADDRESS这个字段不能用?Unhide in a separate CL
Log.v("email", emailAddress);

String version = emails
.getString(emails
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA_VERSION));
Log.v("email version", version);
}
emails.close();
}
cursor.close();
return null;
}
潮汐研究作为海洋科学的关键分支,融合了物理海洋学、地理信息系统及水利工程等多领域知识。TMD2.05.zip是一套基于MATLAB环境开发的潮汐专用分析工具集,为科研人员与工程实践者提供系统化的潮汐建模与计算支持。该工具箱通过模块化设计实现了两大核心功能: 在交互界面设计方面,工具箱构建了图形化操作环境,有效降低了非专业用户的操作门槛。通过预设参数输入模块(涵盖地理坐标、时间序列、测站数据等),用户可自主配置模型运行条件。界面集成数据加载、参数调整、可视化呈现及流程控制等标准化组件,将复杂的数值运算过程转化为可交互的操作流程。 在潮汐预测模块中,工具箱整合了谐波分解法与潮流要素解析法等数学模型。这些算法能够解构潮汐观测数据,识别关键影响要素(包括K1、O1、M2等核心分潮),并生成不同时间尺度的潮汐预报。基于这些模型,研究者可精准推算特定海域的潮位变化周期与振幅特征,为海洋工程建设、港湾规划设计及海洋生态研究提供定量依据。 该工具集在实践中的应用方向包括: - **潮汐动力解析**:通过多站点观测数据比对,揭示区域主导潮汐成分的时空分布规律 - **数值模型构建**:基于历史观测序列建立潮汐动力学模型,实现潮汐现象的数字化重构与预测 - **工程影响量化**:在海岸开发项目中评估人工构筑物对自然潮汐节律的扰动效应 - **极端事件模拟**:建立风暴潮与天文潮耦合模型,提升海洋灾害预警的时空精度 工具箱以"TMD"为主程序包,内含完整的函数库与示例脚本。用户部署后可通过MATLAB平台调用相关模块,参照技术文档完成全流程操作。这套工具集将专业计算能力与人性化操作界面有机结合,形成了从数据输入到成果输出的完整研究链条,显著提升了潮汐研究的工程适用性与科研效率。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值