权限:
批量处理:
在增删改的时候最好使用Contacts Provider的”批量模式",通过创建一个ContentProviderOperation的List,再调用applyBatch()来实现。因为Contents Provider 在一个单一的事务中完成所有的操作,所以数据不会不前后不一致。批量模式,同时也可以插入一个raw contact和它的details data。
修改逆向引用:
当你插入一条新的raw contact和它相关联的一组ContenProviderOperation对象时,你必须通过插入raw contact 的 _ID 当做 RAW_CONTACT_ID,将raw data链接到 rows caontact。然而,当你为data row 创建ContentProviderOperation时,这个值你并不能取到,因为你还没有为这个raw contact row执行这个ContentProviderOperation。为了解决这个问题,ContentProviderOpeation.builder类有了一个withValuesBackReference()函数。这个函数允许你使用之前操作的结果来插入或者修改一列数据。
两个参数:
key:你想修改的那个table column的名称
previousResult:
---------------------------------------------------------------------------------------
乐观的并发控制(optimistic concurrency control):
批量操作允许你通过执行一个不需给仓库加锁的修改事务方法,来实现乐观的并发控制。为了实现这个方法,你应该先申请一个事务,再检查是否有同时执行修改的操作。如果你发现有前后不一致的操作发生,你可以回滚你的事务,重新操作。
同一时间只有一个用户在线,并且同时对数据仓库进行数据访问也是罕见的,这时对于移动设备来说,乐观的并发操作是很有用的。因为锁并没有被用到,没有时间呗浪费在设置锁,或等他其他事物释放锁。
给ContactsContract.RawContacts使用乐观的并发操作时需要按以下几个步奏:
1.和其他数据一同返回raw contact的VERSION列数据
2.通过newAssertQuery(Uri)方法给ContentProviderOperation.Builder对象创建一个强制性的约束。对于这个内容的Uri,使用RawContacts.CONTENT_URI加上 raw contact的 _ID
3.对于ContentProviderOperation.Builder对象,调用withValue()来和你之前接受的version来和VERSION比较。
4.ContentProviderOperation.Builder,调用withExpectedCount()来确保至少有一行数据被这个断言测试过。
5.通过调用builde()来创建ContentProviderOpearion.Builder对象,并将其添加到ArrayList中,再执行applyBatch()
6.执行这个批量事务
如果同一时刻,contact row被其他程序更新了,你也读取了他的数据,并且尝试去修改数据。那么ContentProviderOperation的尝试执行将会失败,整个批量操作将会被放返回。你可以尝试继续这个操作,或者做些其他事。
(详细操作见代码)
---------------------------------------------------------------------------------------------
通过intent做数据的检索和修改
---------------------------------------------------------------------
数据的完整性
因为联系人存储库包含重要和敏感数据,用户期望是正确的和最新的,the Contacts Provider 定义良好的数据完整性规则。当你修改数据的时候,这是你的职责去遵守这些规则。
1.为每一个ContactsContract.RawContacts 添加 ContactsContract.CommonDataKinds.StructuredName。
如果一个ContactsContract.RawContacts 没有ContactsContract.CommonDataKinds.StructuredName,这将会在聚合的时候造成一些问题
2.将ContactsContract.Data行连系到他们的父母ContactsContracts行。
如果没有联系上,这个row将会对程序不可见,这就会对同步适配器产生一些问题。
3.只改变属于你的数据。
记住Contacts Provider经常管理不同账户/在线服务的数据。你应该确保你的程序只修改,或删除那些属于你的数据。只插入数据使用你的账户类型和名称。
4.尽量使用ContactsContract中定义的常量,和他子类中的authorities,cotent URIs,URI path,column name,MIME types,和TYPE value.
使用常量奶奶个能够帮助你避免一些错误。如果有些常量被弃用了,编译器也能够及时地提醒你。
----------------------------------------------------------------------------------------------
自定义数据行
在ContactsContract.Data表中通过自定义你自己的MIME types,你可以在其中增删查改。
---------------------------------------------------------------------------------------------
ContactsProvider 同步适配器(sync adapter)
Contacts Provider 是为了 处理设备和线上的服务之间的同步 而特别设计的。他允许用户下载已存在的设备至新的设备,上传数据到新的账户。无论数据发什么了什么变化,都能够确保用户手上有最新的数据。同步的另一个优势是,及时设备不能够连上网络,通讯录数据还是能够使用。
虽然你可以通过多样的手段实现同步方法,android系统提供了插件式的同步框架,能够自动地执行以下几个任务:
1检查网络是否可用
2基于用户的行为,计划和执行同步任务
3从新执行被停止了的同步任务
---------------------------------------------------------------------------------------------
同步适配器类和文件(sync adapter classes and files)
你可以通过实现AbstractThreadedSyncAdapter来实现一个 sync adapter,并且像程序的一部分那样安装它。系统通过你程序的minifest中的节点来了解你的snyc adapter。xml文件定义了Contact Provider的account type和在线service的和authority,这两者放一起就能定义一个特定的sync adapter。直到用户为sync adapter添加一个账户并且让这个sync能够同步数据。在那个时刻,系统开始管理这个adapter,当需要的时候就叫他去在content provider 和server之间同步数据。
NOTED:利用account type当做sync adapter的一部分身份证明,能允许系统检测和分组,访问同一组织不同的服务的同步适配器。举例,当用户添加一个Google账户到设备上时,所有之前为google services安装的sync adapter会被放在一起;每个sync adapter列出同步装置为不同的Content Provider.
因为大多数services要求用户在获取数据之前先确认下他们的认证信息,所以android system提供一个和sync adapter framework很相似的,使用AbstractAccountAuthenticator的子类的嵌入式认证者的 authentication framework。一个authenticator认证一个用户的身份需要以下几个步骤:
1.收集用户的姓名,密码 或者相似的信息(用户的证书)
2.发送证书至service
3.检查service的回复
如果service接受了证书,authenticator就会为之后的使用者存储证书。因为 authentication framework的使用,AccountManager可以提供任何authtoken身份支持和选择交货。
----------------------------------------------------------------------------------------------
同步适配器的实现 (sync adapter implementation)
为一个Contacts Provider实现一个同步适配器,你创建的android程序必须包含以下几点:
1:一个绑定到同步适配器来响应系统请求的Service组件:
当系统想要开始同步的时候,它开始调用service的onBind方法,来为同步适配器活得一个IBinder对象。这样允许系统去夸进程去调用适配器的方法。
2:一个同步适配器,是AbstractThreadedSyncAdapter子类的一个具体的实例。
这个类的工作是从service上下载数据,将设备的数据上传,解决冲突。主要的工作是在适配器的OnPerformSync()方法中完成的。这个类必须被单例实例化。
3:一个Application的子类
这个类的作用是生成适配器。在OnCreate()方法里实例化一个同步适配器,提供一个static "getter"函数,来返回单例给onBind()方法的同步适配器的service
4:可选项::
5:可选项
6:定义 同步适配器(sync adapter) 和 authenticator 的 xml文件。
同步适配器和authenticator service组件先前就在application 的manifest文件中的
同步适配器service的
可选项:authenticator的
-------------------------------------------------------------------------------------------------------------------
社会流数据(Social Stream Data)
COntactsContract.StreamItems和ContactsContract.StreamItemPhotos表管理来自社交网络的数据。你可以写一个适配器将你network上的数据写入这些个表格,或者你也可以从这个表格中读取数据,展示在你的application中。通过这些资源,你的社交网络服务和程序能够被被集成到Android的社交体验中。
social stream text
流项目和一个raw contact联系在一起。RAW_CONTACT_ID为一个 raw contact 联系到 _ID。raw cantact 的account type和account name被存储在 stream item row
将你来自stream的数据存储在一下列中:
ACCOUNT_TYPE
ACCOUNT_NAME
COMMENTS
TEXT
TIMESTAMP
ContactsContract.StreamItem表同时也为特殊的适配器的使用包含了列SYNC1至SYNC4列
social stream photo
ContactsContract.streamPhotoItem表存储了一个stream item的照片。