Android ContactProvider码源解析

article/2025/10/20 12:56:27

  • Android Contacts源码解析2
      • 4 ContactsProvider模块
        • 1ContactsProvider简介
        • 2数据库创建
        • 3主要数据库的表结构相互关系
          • 1data表
          • 2raw_contacts表
          • 3contacts表
          • 4mimetypes
          • 5其他表

文章转载自:https://blog.csdn.net/kafka_88/article/details/58585607

4, ContactsProvider模块

4.1,ContactsProvider简介:

数据操作层。
ContactsProvider类的结构:
这里写图片描述

ContactsProvider中数据操作基类是AbstractContactsProvider.java,它继承ContentProvider组件类并实现了SQLiteTransactionListener
可以发现,该类是抽象基类,在里面实现了ContentProvider类的insertdeleteupdate三个抽象方法,在这三个方法中在其中使用了事务对数据库进行操作,方法为insertInTransactionupdateInTransactiondeleteInTransaction。该类在对数据库进行事务操作的同时,对子类开放了onBeginonRollbackonCommit事务回调方法,子类可以根据自己的业务特点进行扩展。

以Insert为例,基本时序图为:
这里写图片描述

4.2,数据库创建

数据库的一些概念性知识:

数据库索引:
对数据库表中一个或多个列的值进行排序的结构。排序之后进行搜索会更加有效率,也就是说,索引有助于更快地获取信息。

数据库视图:
将数据库的多个表的多个列组合为一张虚拟的表,称之为视图,方便查询,同时也掩饰了底层数据库的复杂性,把数据库设计的复杂性与用户屏蔽分开。

数据库触发:
触发器是一种特殊类型的存储过程,它在指定的表中的数据发生变化时自动生效。唤醒调用触发器以响应 INSERT、UPDATE 或 DELETE 语句。
常见的触发器有两种:before和after,决定触发的时机。

数据库的创建主要通过ContactsDatabaseHelper和LegacyApiSupport来进行创建。
ContactsDatabaseHelper类是单例类,继承了SQLiteOpenHelper,所以同一时刻不同的ContentProvider只能得到一个数据库引用。

当用户调用ContactsDatabaseHelperOnCreate之后,先完成自己模块内定义的操作,然后执行LegacyApiSupport中的crateDatabase()

这里写图片描述

这里写图片描述

4.3,主要数据库的表结构、相互关系

联系人的数据库文件的位置:
/data/data/com.android.providers.contacts/databases.contacts2.db

数据库中主要的几张表之间的关系:
这里写图片描述

可以发现,`Contacts`表和`raw contact`表是一对多的关系,`Contacts`表是对`raw contact`表记录的聚合,即`Contacts`表中是没有账户(Account)的概念的,而`raw contact`表是联系人特定账户的的概要信息,`Data`表则存储了联系人的详细信息,比如email、电话号码等。
1、data表
  • 该表保存了所有创建过的联系人的所有信息,每条信息占一行,该表保存了两个ID:MimeTypeIDRawContactID,从而将data表和raw_contacts表、mimetypes联系起来。
  • Data表储存所有与RawContract相关具体的信息。表的每一条记录对应一个特定信息,如:名字、电话,email地址, 头像和组信息等。每一记录通过一个mimetype_id字段来表明该行所记录的数据类型。例如,如果row的数据类型是Phone.CONTENT_ITEM_TYPE,那么第一个字段应该保存电话号码,如果数据类型为Email.CONTENT_ITEM_TYPE,那么这一记录的字段应该保存邮件地址。
  • 联系人的所有信息保存在列data1至data15中,各列中保存的内容根据MimeTypeID的不同而不同。如保存号码(MimeTypeID=5)的那行数据中,data1列保存号码,data2列保存号码类型(手机号码/家庭号码/工作号码等)。

Data表的字段主要有:

说明
mimetype_id表示该行存储的信息的类型,外键
raw_contact_id表示该行所属的RawContact,外键
is_primary多个data数据组成一个raw contact,该字段表示此data是否是其所属的raw contact的主data,即其display name会作为raw contact的display name
is_super_primary该data是否是其所属的contact的主data,如果is_super_primary为1则is_primary一定为1
data1~data1515个数据字段,对于不同类型的信息,表示不同的含义,ContactsContract.CommomDataKinds类中定义了与常用的数据类型相对应的一些类,这些类中分别定义了相应数据类型中这些字段表示的含义。一般data1表是主信息(如电话,Email地址等),data2表示副信息,data15表示Blob数据。
data_sync1~data_sync4sync_adapter要用的字段(sync_adapter用于数据的同步,比如你手机中的Gmail帐户与Google服务器的同步)。
data_version数据的版本,用于数据的同步。

Data表的索引Index有:
_id data表的Id列
Mimetype_id 存储的信息的类型
raw_contact_id 所属的raw_contact的id

Data表的触发Trigger有:
[data_updated] 数据更新时触发RawContacts表更新数据update {@link RawContacts#VERSION}
[data_deleted] 数据被删除时触发RawContacts表更新数据update {@link
RawContacts#VERSION}

2、raw_contacts表
  • raw contact表描述了联系人每个账户下的数据,根据账户名和账户类型字段进行区分。即同一个联系人可能在raw contact表中有多个记录,每个记录分属于不同的账户。表中的每一行表示一个联系人某一特定帐户的信息,存储Data表中一些数据行的集合及一些其他的信息。

  • 当插入一个raw contact或当一个raw contact所属的一个data改变时,系统会检查这个raw contact跟其他的raw contact是否可以匹配(比如如果两个raw contact的data包含相同的电话号码或名字),如果匹配他们就会被综合到一起,也就是说他们会属于同一个contact,表现为在RawContact表中他们引用的cantact_id是一样的。联系人姓名、组织、电话号码、Email或昵称的改变会引发raw contact的重新聚合。

raw contact的主要字段有:

说明
account_id本行数据关联的联系人账户
contact_id本行数据关联的Contact表数据
raw_contact_is_read_only是否只读
version版本
deleted是否已被删除
last_time_contacted上次联系时间
Times contact联系次数
starred收藏?
indicate_phone_or_sim_contactSim卡/手机联系人

raw contact的索引有:

[] PRIMARY[_id] AUTOINCREMENT 
[raw_contact_sort_key1_index][sort_key] 
[raw_contact_sort_key2_index][sort_key_alt] 
[raw_contacts_contact_id_index][contact_id] 
[raw_contacts_source_id_account_id_index][sourceid] [account_id] 

raw contact的触发有:

[raw_contacts_deleted]
当一个Raw_contacts被删除的时候,自动删除Data表中相关的Data。(即Raw_contacts的id为删除的那个id)

[raw_contacts_marked_deleted]
Triggers that update {@link RawContacts#VERSION} when the contact is marked for deletion。

3、contacts表

每个联系人占一行,该表保存了联系人的ContactID、联系次数、最后一次联系的时间、是否含有号码、是否被添加到收藏夹等信息。
Contact表不能被主动创建,Contact表中的一行表示一个联系人,它是RawContact表中的一行或多行的数据的组合。这些RawContact表中的每一行,表示同一个人的不同的帐户信息。Contact中的数据由系统组合RawContact表中的数据自动生成,不可以直接向这个表中插入数据,当一个raw contact被插入的时候,系统会首先查找Contact表看是否有记录跟插入的raw contact表示同一个人,如果找到了,则把找到的这个contact的_ID插入raw contact记录的CONTACT_ID字段,如果没有找到,则系统自动插入一个Contact记录并把它的_ID插入新插入的raw contact的CONTACT_ID列。

Contacts表是对raw contact表按照account type和account name进行的聚合。
Contacts表的聚合逻辑在ContactAggregator.java文件中,该类中定义了一个成员方法.

Contacts表的主要字段:

说明
name_raw_contact_id本行数据关联的联系人账户,外键
last_time_contacted上次联系的时间
raw_contact_is_read_only是否只读
lookup查找字符串
indicate_phone_or_sim_contactSim卡/手机联系人
photo_id照片Id,外键
starred收藏

Contacts表建立的索引:

[contact_last_updated_timestamp]   联系人上次更新时间
[has_phone_number]              联系人是否有电话号码
[name_raw_contact_id]      raw contact ID
4、mimetypes

该表定义了所有的MimeTypeID,即联系人的各个字段的唯一标志。
主要类型如下:

说明
vnd.android.cursor.item/phone_v2电话
vnd.android.cursor.item/name姓名
vnd.android.cursor.item/email_v2邮件
vnd.android.cursor.item/postal-address_v2通信地址
vnd.android.cursor.item/organization组织
vnd.android.cursor.item/photo照片
5,其他表

calls表
最的通话记录
android.provider.CallLog.Calls

说明
_id行id
number通话电话号码
data拨打该电话号码的开始时间(以1970-01-01 00:00:00)计算到当前的时间差以毫秒为单位
duration打电话持续时间,以秒为单位
type呼叫类型(“1”来电,“2”外拨,“3”未接)
new呼叫已被确认与否。“1”代表来电,外拨,“0”代表未接
name如果联系人存在,与电话号码相关联的联系人的名字
numbertype如果联系人存在,与电话号码相关联的电话类型
numberlabel如果联系人存在,自定义数字类型相关联的电话号码数字标签(例如VOICE)(numbertype 为1-7时numberlabel为null;为0时显示自定义标签)
typedial拨打电话的类型(语言电话、视频电话)

phone_lookup表

说明
data_id通过data_id可以找到 data表中相对的数据。
raw_contact_id通过raw_contact_id 可以找到 raw_contact_表中相对的数据
normalized_number原始电话号码
min_match将每个电话号码逆序排列

groups表
ContactsContract.Groups

说明
_id行id
package_id
account_name账户名字
account_type帐户的类型
sourceid
version 版本;当列或相关数据修改时,将会自动修改
dirty版本发生改变的标记
title这组显示的标题
title_res
notes这组的注释
system_id如果它是一个系统组,这个组的ID,即对同步适配器具有特殊意义的一组,否则返回null。
deleted删除标记;0 or 1;1 表示标记为被删除。
group_visible群组是否在UI中 是否可见;是(1),否(0)
should_sync这组是否应该同步,是(1),否(0)
sync1到sync4

accounts表
android.accounts.Account

说明
account_name账户名字
account_type账户类型

settings表
android.provider.ContactsContract.Settings

说明
account_name账户名字
account_type账户类型
ungrouped_versible标志该组是否在UI中可见;“1”可见,“0”不可见
should_sync根据同步适配器定义的模式,这个标志控制此数据源的顶级的同步行为。

agg_exceptions表
ContactsContract.AggregationExceptions
_id
type 异常的类型:TYPE_KEEP_TOGETHER(1),TYPE_KEEP_SEPARATE(2)或TYPE_AUTOMATIC(3)。
raw_contact_id1 A reference to the _ID of the raw contact that the rule applies to.
raw_contact_id1 A reference to the other _ID of the raw contact that the rule applies to.
raw_contact_id1和raw_contact_id2之间通过规则(type)引用

sqlite_sequence表
SQLite中的自动编号列
name 自动编号字段所在的表
seq 当前用到的序号


http://chatgpt.dhexx.cn/article/gpxn3aFk.shtml

相关文章

Contacts Provider基础

作为四大组件之一的ContentProvider工作中我们很少会用到自己自定义的ContentProvider,用到的最多的就是系统提供的。官方文档提供了两种系统ContentProvider,一种是CalendarProvider,一种是Contacts Provider。今天我们的主角就是Contact Provider。 The Contacts Provider is…

Error: invalid code, hints: [ req_id: * ]

1、问题描述:这个问题是在处理订单支付时需要用户登录遇到的,具体报错信息如下: 2、报错原因: 当前开发者的appid没有支付权限导致 3、解决方案: 需要负责人给分配对应的权限

This application’s bundle identifier does not match its code signing identifier.

今天使用carthage更新第三方后莫名出现真机云心失败,提示 This application’s bundle identifier does not match its code signing identifier. 解决方法: /usr/local/bin/carthage copy-frameworks 进入Building Phases 单击并在New Run Script Phase中添加脚本 将/usr/lo…

Code Sign error: a valid provisioning profile matching the application's Identifier 'com.yourcompany

出现这个错误的原因是因为:appid和provisioning profile不匹配 !有两种解决的办法:重新下载provisioning profile,或者可能因为:生成证书和appid 所用的根证书不同,最好重新都生成然后下载。(这…

ANTD react 手机号(验证码)登陆 + 账号登陆(图形验证码)

这种页面可能是大家常用的,但重写比较费时间,之前没有搜到完整的,在这里自己总结一下,方面复用 代码: <LoginFormformRef{formRef}initialValues{{autoLogin: false}}onFinish{async values > {await handleSubmit(values as LoginParams)}}><Tabs activeKey{type…

Springboot+axios+vue使用VerifyCodeUtils工具类实现验证码图片功能

一、环境准备 ideajava 1.8maven 3.6.3操作系统&#xff1a;window10vue.min.jsaxios.min.js 二、VerifyCodeUtils工具类 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import ja…

Identity and Authentication - Common Authentication Methods

Username and Passwords This is the most common method of identifying users in the age of Software as a Service (SaaS) 解释上面的图中的步骤&#xff1a; Login Request: POST /login postuser {username: users,password: pws }Find users: SELECT * FROM databa…

iOS code signing identity 配置

PROJECT 和 TARGET 中都要选:code signing identity: 调试统一都选 developer, 发布统一都选 distribution provisioning Profile 也要选. 过期和无效的证书及时删除, 避免 ambiguous 警告. 选择正确的证书配置后仍然报错, clean 一下重启 xcode 还不行~~~重启电脑

Invalid CAPTCHA response. Please try again. (Code: 1201)

项目场景&#xff1a; Invalid CAPTCHA response. Please try again. (Code: 1201) 解决方案&#xff1a; 直接使用隐私浏览器打开即可。

经典的Embedding方法Word2vec

提起Embedding,就不得不提Word2vec,它不仅让词向量在自然语言处理领域再度流行&#xff0c;更为关键的是&#xff0c;自2013年谷歌提出Word2vec以来&#xff0c;Embedding 技术从自然语言处理领域推广到广告、搜索、图像、推荐等深度学习应用领域&#xff0c; 成了深度学习知识…

embedding表示方法及原理

目录 1.前言2.embedding表示方法2.1 word2vec embedding2.2 neural network embedding2.3 graph embedding 3.参考文献 1.前言 近几年embedding的使用及优化在各种比赛、论文中都有很多的应用&#xff0c;使用embedding表示特征的空间表示也在各种应用中确定是一种很有效的特征…

深度学习:词嵌入Embedding

http://blog.csdn.net/pipisorry/article/details/76095118 词嵌入 词嵌入其实就是将数据的原始表示表示成模型可处理的或者是更dense的低维表示&#xff08;lz&#xff09;。 One-hot Embedding 假设一共有个物体&#xff0c;每个物体有自己唯一的id&#xff0c;那么从物体…

什么是embedding(把物体编码为一个低维稠密向量),pytorch中nn.Embedding原理及使用

文章目录 使embedding空前流行的word2vec句子的表达训练样本损失函数输入向量表达和输出向量表达 v w v_{w} vw​ 从word2vec到item2vec讨论环节pytorch中nn.Embedding原理及使用pytorch中nn.Embedding原理及使用一些注意的点 参考 简单来说&#xff0c;embedding就是用一个低维…

讲清楚embedding到底在干什么

要搞清楚embeding先要弄明白他和one hot encoding的区别&#xff0c;以及他解决了什么one hot encoding不能解决的问题&#xff0c;带着这两个问题去思考&#xff0c;在看一个简单的计算例子 以下引用 YJango的Word Embedding–介绍 https://zhuanlan.zhihu.com/p/27830489 On…

一文读懂Embedding

文章目录 一、**什么是Embedding&#xff1f;**二、One-Hot编码三、**怎么理解Embedding****四、Word Embedding** 一、什么是Embedding&#xff1f; “Embedding”直译是嵌入式、嵌入层。 简单来说&#xff0c;我们常见的地图就是对于现实地理的Embedding&#xff0c;现实的…

Embedding的理解

Embedding 嵌入&#xff0c;我们可以将其理解为一种降维行为。可以将高维数据映射到低维空间来解决稀疏输入数据的问题。 它主要有以下三个目的&#xff1a; 在 embedding 空间中查找最近邻&#xff0c;这可以很好的用于根据用户的兴趣来进行推荐。作为监督性学习任务的输…

BERT的三个Embedding详解

BERT将输入文本中的每一个词&#xff08;token)送入token embedding层从而将每一个词转换成向量形式 两个嵌入层&#xff0c;segment embeddings和 position embeddings token embedding token embedding 层是要将各个词转换成固定维度的向量。在BERT中&#xff0c;每个词会被…

Embedding层的理解

Embedding层的理解 转载自&#xff1a;原文&#xff1a;深入理解 Embedding层的本质_罗小丰同学的博客-CSDN博客_embedding层 首先&#xff0c;我们有一个one-hot编码的概念。 假设&#xff0c;我们中文&#xff0c;一共只有10个字。。。只是假设啊&#xff0c;那么我们用0-…

Embedding理解与代码实现

Embedding 字面理解是 “嵌入”&#xff0c;实质是一种映射&#xff0c;从语义空间到向量空间的映射&#xff0c;同时尽可能在向量空间保持原样本在语义空间的关系&#xff0c;如语义接近的两个词汇在向量空间中的位置也比较接近。 下面以一个基于Keras的简单的文本情感分类问…

深度学习中Embedding层有什么用?

2019年03月24日15:23:32更新&#xff1a; 由于CSDN图片经常显示不出来&#xff0c;本文最新链接请点击&#xff1a;https://fuhailin.github.io/Embedding/ 博主所有博客写作平台已迁移至&#xff1a;https://fuhailin.github.io/ &#xff0c;欢迎收藏关注。 这篇博客翻译自国…