ContactsProvider2

android11 特殊符号开头的联系人显示到“#”分组下面 Android11 Contacts以及ContactsProvider源码修改 阅读详情

本篇不全也不细,只是根据按照个人理解和工作中遇到的问题,总结了个人认为的要点。

1. Android的数据库体系

  • 1.1. 概述
  • 1.2 uri结构

2. ContactsProvider2

  • 2.1. 概述
  • 2.2. Contacts2.db中的表
  • 2.3. ContactProvider2中的实现
  • 2.4. 批量访问

1. Android的数据库体系

1.1. 概述

Android的数据库体系可以分为三个层次:

  1. ContentProvider层;ContentProvider将对数据的增删改查操作进行了抽象,具体实例会注册到AMS中,提供跨进程的服务。ContentProvider可以用于管理各种数据存储源的访问,包括结构化数据(SQLite)和非结构化数据(如图像文件)。
  2. SQLiteDatabase/SQLiteOpenHelper;这部分代码位于“/frameworks/base/core/java/android/database/sqlite/”,ContentProvider要借助于这些框架层的类来和SQLite数据库进行交互。
  3. SQLite数据库;这部分属于native层,代码位于external/sqlite。

ContentProvider不支持线程安全,但SQLite是支持线程安全的(编译前将 宏SQLITE_THREADSAFE 设置为1)。
多个进程可以同时打开一个database,而且可以同时执行SELECT操作,但是同一时间只能有一个进行修改操作。
下面的简图展示了我们使用uri访问database的方式,其中ContentProvider在ActivityManagerService中的register可能是自己所在进程启动时做的,也可能是ActivityManagerService收到uri请求后启动ContentProvider时做的。ContentResolver和ActivityManagerService根据uri中的"authority"来确定要访问的ContentProvider。
在这里插入图片描述

1.2 uri结构
基本结构

[scheme:]scheme-specific-part[#fragment]

进一步划分

[scheme:][//authority][path][?query][#fragment]
path可以有多个,每个用/连接,比如scheme://authority/path1/path2/path3?query#fragment。

query参数可以带有对应的值,也可以不带,如果带对应的值用=表示,如:
scheme://authority/path1/path2/path3?id = 1#fragment,这里有一个参数id,它的值是1
query参数可以有多个,每个用&连接,如
scheme://authority/path1/path2/path3?id = 1&name = xiaofang&age#fragment
这里有三个参数:
参数1:id,其值是:1
参数2:name,其值是:xiaofang
参数3:age,没有对它赋值

在android中,scheme、authority都是必须要有的,而至于path、query和fragment,它们都是选择性的,可以有也可以没有,但顺序不能变,比如:
"path"可不要:scheme://authority?query#fragment
"path"和"query"可都不要:scheme://authority#fragment
"query"和"fragment"可都不要:scheme://authority/path
“path”,“query”,"fragment"都不要:scheme://authority
等等……

终极划分

[scheme:][//host:port][path][?query][#fragment]


2. ContactsProvider2

2.1. 概述

ContactsProvider2是Android一个很成熟的源生组件,用于管理联系人数据相关的存储区。Google对ContactsProvider2有一个比较详细的介绍,下面是相关链接:
https://developer.android.com/guide/topics/providers/contacts-provider

ContactsProvider2管理了两个database,一个是"contacts2.db",另外一个是"profile.db";本篇着重写contacts.db相关的内容。
在这里插入图片描述

2.2. Contacts2.db中的表

“contacts2.db”数据库中存储了联系人、通话记录和Account等数据。
由于联系人的信息字段比较多,包含了号码、地址、Email和头像等信息,所以数据库中的数据表也比较多;为了提高查询速度,还创建了视图和索引;另外还有触发器。

Android P源码中数据表有30多个,视图有11个;这里就不一一列出了,太占地方了,哈哈。
我们需要搞清楚这些表之间的关系,特别是几个存储重要信息的表,下面是几个重要表的ER图
在这里插入图片描述
表“Contacts”中的数据是在数据插入表“raw_contact”之后,在Transaction的回调onCommit调用序列中插入的。

联系人相关的数据并没有存储在raw_contact表中,而是存储在了Data表中;一条raw_contact数据在Data表中对应多条数据。Data表中有15个data字段,每个字段存储的是什么信息要根据列"mimetype_id"来决定,该列的取值来自"account"表的主键"_ID"。
协定类ContactsContract.java中为data字段定义了映射名称类,如下表:

映射类数据类型备注
ContactsContract.CommonDataKinds.StructuredName与该数据行关联的raw contact的姓名数据。一位raw contact只有其中一行。
ContactsContract.CommonDataKinds.Photo与该数据行关联的raw contact的主要照片。一位raw contact只有其中一行。
ContactsContract.CommonDataKinds.Email与该数据行关联的raw contact的电子邮件地址。一位raw contact可有多个电子邮件地址。
ContactsContract.CommonDataKinds.StructuredPostal与该数据行关联的raw contact的邮政地址。一位raw contact可有多个邮政地址。
ContactsContract.CommonDataKinds.GroupMembership将raw contact链接到联系人提供程序内某个组的标识符。组是帐户类型和帐户名称的一项可选功能。联系人组部分对其进行了更详细的描述。

以“ContactsContract.CommonDataKinds.Email”和“ContactsContract.CommonDataKinds.StructuredName”为例,前者用于联系人的Email信息,后者用于联系人的名字信息; 它们分别在Data表中有一条记录,而且都使用了“data1”、“data2”和“data3”这三个字段,但是每个字段在两条记录中分别存储了不同的信息,如下图:
在这里插入图片描述


2.3. ContactProvider2中的实现

下面是ContactsProvider2的类继承关系图:
在这里插入图片描述
ContactsProvider2直接继承了AbstractContactsProvider.java这个类,它的很多功能都继承自这个抽象父类,看代码时这个抽象父类的代码也是重点。
ContactsProvider2中定义了UriMatcher对象sUriMatcher,并在static块中进行了初始化:

matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_ID_DATA);
...
matcher.addURI(ContactsContract.AUTHORITY, "data", DATA);

ContractsProvider2会将接收到的uri和sUriMatcher进行匹配,即根据uri中的path确定要访问的table。
比如,我们向Data表中增加一条数据记录,那么我们会使用

ContactsContract.Data.CONTENT_URI,即"content://com.android.contacts/data"

insertInTransaction方法使用sUriMatcher进行匹配后返回”DATA”,然后在switch的对应case语句中处理这条增加数据的请求。

由于"contacts2.db"中的表比较多,而App层只是通过uri发送请求,那么相关表直接的数据维护逻辑是在ContactsProvider2中完成的,这也方便了App层的使用。为了维护数据一致性和原子性等,ContactsProvider2.java的增/删/改都使用了事务(Transaction),下面的流程图展示了insert操作的事务处理流程,其他操作类似:
在这里插入图片描述

2.4. 批量访问

可以使用 ContentProviderOperation 类中的方法创建一批访问调用,然后通过 ContentResolver.applyBatch(…) 应用这些调用。如果某次批量修改需执行大量操作,则可能会阻塞其他进程,导致整体用户体验不佳。可以将想执行的修改操作尽量分散到各个集合中,并为一项或多项操作设置挂起点。挂起点是一个 ContentProviderOperation 对象,并且其 isYieldAllowed() 值设置为 true。当ContactsProvider2遇到挂起点时,它会暂停其工作,让其他进程运行,并关闭当前事务。当ContactsProvider2再次启动时,它会继续执行 ArrayList 中的下一项操作,并启动新事务。

挂起点会导致每次调用 applyBatch() 时产生多个事务。因此,应为一组相关数据行的最后一项操作设置挂起点。例如,应该为一组操作中添加raw contact行及其关联数据行的最后一项操作设置挂起点,或者针对一组与某位联系人相关的行的最后一项操作设置挂起点。
挂起点也是一个原子操作单元。无论访问成功还是失败,两个挂起点之间的所有访问均以一个单元的形式呈现。如果不设置任何挂起点,则最小的原子操作即为整个批量操作。如果使用挂起点,则可以防止操作降低系统性能,还可确保部分操作为原子操作。


结束
AVS3代码阅读HPM4.0 参考AVS3代码阅读(HPM6.0)(一.整体架构以及CU划分部分代码) 版本:HPM4.0 核心文件:app_encoder.c   要做的是帧间预测,所以前面的函数先暂时不管了,挖个坑以后再填。直接从enc_pic看起。 enc_pic()    ... 阅读详情

相关推荐

告别盲调!用Synopsys VIP搭建PCIe 5.0验证环境,手把手搞定链路训练与均衡调试

本文详细介绍了基于Synopsys VIP搭建PCIe 5.0验证环境的实战指南,重点解析了链路训练(LTSSM)与均衡调试的关键技术。通过配置VIP组件、设计验证平台架构及实战调试技巧,帮助工程师高效解决PCIe 5.0验证中的常见问题,提升芯片验证效率与可靠性。

weixin_28700411的博客 459

Android ContactsProvider源码分析

Android源码目录packages\providers下的应用是下载,通话等内置基本应用提供数据存储和操作的provider应用,本文章将针对ContactsProvider源码的架构和实现展开分析。(注:本文使用使用android4.0版本进行分析) 1、架构设计       ContactsProvider中数据操作基类是AbstractContactsProvider.java(参见

Mr. DU 4220

Moltbot 超详细安装使用教程(初学者版)

你在外面逛街,用微信/Telegram 发消息说"帮我查一下明天的天气"它立刻帮你查好并回复你说"帮我在电脑上新建一个文件夹叫'工作文档'"它真的帮你在电脑上创建了这就是 Moltbot ——一个能真正帮你干活的 AI 助手。API Key 就像是一把"钥匙",让 Moltbot 能够使用 AI 服务。

weixin_51040479的博客 2017

ContactsProvider2 通讯录部分源码

<br />/*<br /> * Copyright (C) 2009 The Android Open Source Project<br /> *<br /> * Licensed under the Apache License, Version 2.0 (the "License");<br /> * you may not use this file except in compliance with the License.<br /> * You may obtain a copy of th

Android_wy的专栏 6285

Zynq AXI DMA实战:5分钟搞懂S_AXIS_S2MM和M_AXIS_MM2S数据流(附Vivado配置截图)

本文通过Vivado实战配置,清晰解析了Zynq平台AXI DMA IP核中S_AXIS_S2MM和M_AXIS_MM2S数据流的核心概念与连接方法。文章重点阐述了数据流向、主从关系及接口命名规则,并提供了从ADC数据采集到DDR存储,再从DDR读取数据发送至DAC的完整双向数据流搭建指南,帮助工程师快速避坑。

weixin_29200741的博客 451

CGAL AlphaShape算法(自适应Alpha值,二维版本)

CGAL AlphaShape算法(自适应Alpha值,二维版本)

dayuhaitang1的博客 2325

contacts2操作通讯录方法(一)

下载: contact_v2.java ContentValues values = new ContentValues(); Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values); long rawContactId = ContentUris.parseId(rawContactUri)

longxingtianxia_fly的专栏 1348

17 指挥AI写Mamba相关模型代码,快速适配大模型场景

本文为《30天掌控AI编程:从指令到落地,手把手教你指挥AI写代码》系列第十七篇,属于第三阶段多场景实战核心内容。本篇聚焦当下大模型领域热门的**Mamba架构**,针对零基础大模型开发、无深度学习基础的使用者,拆解指挥AI生成Mamba基础模型、微调适配、推理部署代码的核心方法,覆盖Mamba基础模块搭建、简易序列建模、小样本微调、本地推理等高频场景,提供可直接复用的高质量指令模板、完整可运行代码、环境配置与避坑指南,无需精通Transformer、状态空间模型等底层原理,轻松上手Mamba大模型开发。

coreopt的博客 61

Android Contact provider基础

Contact providerContact provider是一个强大而又灵活的 Android 组件,用于管理设备上有关联系人数据的中央存储库。 Contact provider是您在设备的联系人应用中看到的数据源,您也可以在自己的应用中访问其数据,并可在设备与在线服务之间传送数据。 提供程序储存有多种数据源,由于它会试图为每个联系人管理尽可能多的数据,因此造成其组织结构非常复杂。 为此,该提

Wtoria的博客 9578

桌面运维工程师面试题详解(一)

桌面运维工程师面试题详解(一)

jks212454的博客 1426

【C#程序员入门AI】AI应用的操作系统:Semantic Kernel 2026实战

用户ID用户信息

人工智能AI技术 1251

API Guides > Contacts Provider (二)

Data From Sync Adapters 用户直接输入联系人的数据到设备中,但是也可以通过sync adapters从服务器上获取联系人的数据。sync adapter 会自动同步设备和服务器上的数据。sync adapter运行在后台,由系统来控制。系统调用ContentResolver去管理数据。 在Android中,和sync adapter一起工作的服务器是由账户类型表示

q2014818的专栏 847

强化学习优化多目标冲突推理的决策过程设计

1. 背景介绍 强化学习(Reinforcement Learning,RL)作为机器学习的一个重要分支,近年来在计算机科学和人工智能领域取得了显著的进展。其核心思想是通过试错来学习最优策略,从而在复杂的环境中实现目标。然而,在多目标冲突推理(Multi-Objective Conflict Reasoning,MOCR)问题上,强化学习面临着诸多挑

AI天才研究院 1513

Android 泰语/缅甸语/捷克语下,Contacts列表中联系人出现排序错乱的

修改ContactsProvider2.java文件 public static final String SECTION_HEADING = "SUBSTR(%1$s,1,1)";  SUBSTR(%1$s,1,1) 改为 SUBSTR(%1$s,1,2)

曹浩洋的专栏 1158

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

android联系人开发文档,Android联系人模块分析(一)

Android联系人模块分析(一)联系人模块是Android系统中的一个重要的功能模块,目前Android市场上有大量的基于通讯录的应用,本人计划写出系列文章详细介绍联系人模块的结构和使用。作为开头,本篇文章将对ContactsProvider做个简要的介绍。Android系统将联系人的信息存储在sqlite数据库中,并通过ContactsProvider提供查询、更新、删除等操作。所以如果需要掌...

weixin_39744384的博客 448

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

android短信选择收件人时,号码搜索联系人修改成任意位置开始中间匹配

ContactsProvider2.java 中的queryLocal函数,修改方法如下:    case CALLABLES_FILTER:       ......     if (searchPhoneNumber) {                                ......                             sb.append(Data

曹浩洋的专栏 1339

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Android ContentProvider 一】关于ContactsContract.CommonDataKinds.Phone.CONTENT_URI的一点理解

一切都要从ContactsContract.CommonDataKinds.Phone.CONTENT_URI说起,前两天

heyzqt 6002

Android数据库内容变化的监听

Android数据库内容变化的监听

fjjjyf的博客 2692

Android2.3修改联系人头像的尺寸和大小

从联系人列表ContactsListActivity.java开始找起,当长按某一个联系人时会弹出Dialog(其实是一个ContextMenu),需找menuitem,找到了case MENU_ITEM_EDIT,这里面会有一个Intent intent = new Intent(this,EditSimContactActivity.class),这是跳转到sim卡联系人,其实还有一个Edit

A2BGeek的专栏 2289

android信息从联系人添加收件人,在联系人多选界面(联系人中有Google账户)搜索时,搜索结果出现排序错误的问题

Google账户mtkshanghai@gmail.com中有很多合并联系人且联系人中有相同的电话号码,从而导致取group分组(PhoneBookIndex)的title和数量,和搜索结果list中的联系人数量不相等, 因为搜索到联系人list的SQL语句会按电话号码分组,相同的号码会被当成一条。 修改ContactsProvider2.java文件case PHONE_EMAIL_

曹浩洋的专栏 1231

android 泰国/缅甸语/捷克较低,Contacts联系出现精神错乱之类的问题清单

更改ContactsProvider2.java文件 public static final String SECTION_HEADING = "SUBSTR(%1$s,1,1)"; SUBSTR(%1$s,1,1)至SUBSTR(%1$s,1,2) 转载于:https://www.cnblogs.com/yxwkf/p/5027445.html...

weixin_30596343的博客 135

android 泰语/缅甸语/捷克语下,Contacts列表中联系人出现排序错乱的问题

修改ContactsProvider2.java文件 public static final String SECTION_HEADING = "SUBSTR(%1$s,1,1)";   SUBSTR(%1$s,1,1) 改为 SUBSTR(%1$s,1,2)

曹浩洋的专栏 1487

在信息收件人里输入号码,不要匹配到电话本里的服务号码

假设电话本里存在SDN(服务号码):"*666" 发送信息,在收件人栏里输入“”,这时会匹配到电话本里的"*222" 如果不希望匹配到服务号码,只是发送给222这个号码,需要做以下修改   [SOLUTION]   1. 修改ContactsProvider2.javas --> PhoneLookupProjectionMap的定义: .add(PhoneLookupC

曹浩洋的专栏 926

Android 之往通讯录中添加数据和查询数据【转】

http://blog.youkuaiyun.com/hosterZhu/archive/2011/01/20/6154461.aspx    首先 我们要在E:\android-sdk-windows\platforms\android-8\sources\ContactsProvider  找到源码 !  因为android自带的通讯录也是通过ContentProvider对外共享数据。  贴...

lcdxwhj2003的专栏 278

Android之联系人处理

联系人处理 Android联系人数据存储框架 联系人数据存储在联系人数据源组件ContactsProvider2中,与一般的数据源存储组件相比,ContactsProvider2更复杂。其中的数据库包含多个表,提供的Uri也更丰富。 联系人数据由3部分组成,联系人基本信息表,如姓名,联系人账号记录表,每个联系人在不同的账号系统下都有相关的信息;联系方式表,联系人具体联系方式数据。 辅助功...

hebeind100的博客 149
上一篇: Service
下一篇: 设计模式小结
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值