Content Provider
在数据处理中,Android通常使用Content Provider的方式。Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据的增、删、改、查的操作。Android并不提供所有应用共享的数据存储,采用content Provider,提供简单便捷的接口来保持和获取数据,也可以实现跨应用的数据访问。简单地说,Android通过content Provider从数据的封装中获取信息。
Content provider使用Uri的方式来定位信息。以“content://” 开头来表明这是一个content URI。例如“content://contstans/5”,其中“content://constans”称为base URI,相当于数据的namespace,它的结构可以更为复杂,可以有多层结构。例子中的“5”,则是具体实例的标识。
一般来讲,Android的数据存储有4种方式:
1、 Preferences,参见Preference的使用,通常都是键值对(name-value pair)。
2、文件:在手机设备或者外设上存储,缺省的只能由创建的应用访问。
3、数据库(RDBMS):SQLite方式,参见SQLite的使用,由创建的应用访问。
4、网络:Android提供API远程在服务器上存储数据。
如果我们需要在应用中共享,采用Content Provider。无论数据具体的存储方式,Content Provider提供了一个统一的接口。数据将采用类表格的方式提供,有行有列,列表示不同属性的数据,例如电话号码、电邮地址等。每个记录(每行)都有一个唯一的_ID字段来标识。在以后具体的代码中看更直观看出。
原生providers
Android提供一些原生的content provider,来往问系统中的视频、图像和联系人信息等等。例如联系人的URI为“content://com.android.contacts /contacts”,原生的providers一般都有定义,例如联系人为 ContactsContract.Contacts.CONTENT_URI。由于系统不同版本可能会存在差异,我们应尽可能使用系统的定义。
在android.provider的包中,可以查看原生的provider,例如有AlarmClock、Browser、CalendarContract、CallLog、 ContactsContract(包括有Contacts,Groups,PhoneLookup等)、MediaStore(Audio 『Albums、Artists、Genres、Playlists』、Files、Images、Video)和Setting。
通过Content Providers读取信息
我们利用原生provider联系人来看看如何来读取信息,联系人的数据结构比较复杂,后面会详细介绍,这里我们将尽可能简化,先对Content Provider有个直观的认识。核心是通过managedQuery( )来获取Cursor。Cursor实际返回是一个二维的表格,有行有列,行是具体的元素,列是该元素具体的属性。整个方式和SQLite非常相似。
//可以很方便将Cursor的内容映射到ListActivity上,具体参见Android学习笔记(四十二):SQLite,ListView,ContextMenu
public class Chapter26Test1 extendsListActivity {
private String[] INFO = new String[]{
ContactsContract.Contacts._ID, //对于Content Provider返回数据表格而言,注意唯一标识_ID通常是必须读取的,否则很容易报错
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor contactCursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO, null,null,null);
ListAdapter adapter = new SimpleCursorAdapter(this,
R.layout.chapter_22_test1,contactCursor,
new String[]{ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.HAS_PHONE_NUMBER},
new int[]{R.id.c22_name,R.id.c22_gravity});
setListAdapter(adapter); //偷偷懒,本例子直接利用了Android学习笔记(四十二)中SQLite例子中的xml
}
}
说说Android联系人信息的组织结构及读取
这是Android给出的联系人组织结构图。分为三层。
第一层,Contact,即ContactContract.Contacts,是整合的联系人信息。
第二层,RawConact,即 ContactContract.RawContact,记录的是该联系人来自某信息源的信息,例如本地输入的,来自Google的,从微软 Exchange中导出的,或则来自某个社交网站的信息。每个RawContact记录的信息都来自同一信息源。
第三层,Data,即 ContactContract.Data,是具体的信息存储,例如记录联系人姓名,email信息,家庭电话,手机电话信息等等,每一个Data都存放一个具体的信息。在Data中的MIME TYPE说明存储信息的类型。具体在ContactContract.CommonDataKinds中定义。每个Data中有DATA1-DATA15 个字段来存储信息,各字段所代表的含义,也可以在CommonDataKinds中具体查到。
下面,我们一层一层地读取联系人信息,将更清晰地看到这个结构。要读取详细信息,对于Content Privider,关键是Uri逐层定位,才能获取信息。为了清晰表述,我们将整个路径写出来。
第一层信息,将返回联系人列表中的多个Contacts,Uri为ContactsContract.Contacts.CONTENT_URI
private String[] INFO_1= new String[]{
ContactsContract.Contacts._ID,//这是每个row,也就是每个联系人的唯一的ID标识
ContactsContract.Contacts.DISPLAY_NAME,
};
Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO_1,null,null,null);
cursor是表格形式,每一个行表示一个联系人。要 读取哪些列,在第二个参数String[]中定义。可以选取那些列,在Android Reference中的ContactsContract.Contacts中的Column中可以查到。最关键的列信息为_ID,它是行,也就是每个联系人的唯一标识。除此之外,每个联系人的信息会根据旗下的RawContact进行整合,因此,我们可以查到联系的名字 ContactsContract.Contacts.DISPLAY_NAME等。
利用Contacts._ID,我们可以检索第二层的信息。
第二层信息,将返回某联系人的多个RawContacts
同样,返回表格中的列,可以查看 ContactsContract.RawContacts中查看。我们选取下面的信息,此外,如果要查看信息的来源,例如来自com.google,可通过RawContacts.ACCOUNT_TYPE和RawContacts.ACCOUNT_NAME两个列查看。
private String[ ] INFO_2 = {
ContactsContract.RawContacts._ID, //这是RawContact的唯一标识
ContactsContract.RawContacts.CONTACT_ID, //这是该RawContact关联的Contact._ID
};
通过查询全部的RawContacts,通过条件检索,要求联系人的ID为指定的某联系人。在下面的例子在managedQuery中给出了param3和param4的条件,注意参数3,如果我们有多个条件,可以用AND等逻辑符合进行表述。
Cursor cursor = managedQuery(ContactsContract.RawContacts.CONTENT_URI ,
INFO_2 ,
RawContacts.CONTACT_ID + "=?" ,
new String[]{String.valueOf(contactId)} ,
null);
通过RawContacts._ID,我们可以往下检索RawContacts下面各Data的信息内容。
第三层信息:将返回某RawContact的各Data的信息
可查询各列的信息见ContactsContract.Data的介绍。
private String INFO_3[] = {
ContactsContract.Data._ID, //这是Data信息块的唯一标识
ContactsContract.Data.CONTACT_ID, //关联第一层信息的CONTACT_ID
ContactsContract.Data.RAW_CONTACT_ID, //关联第二层信息的RAW_IDCONTACT_ID
ContactsContract.Data.MIMETYPE, //具体含义可查ContactsContract.CommonDataKinds
ContactsContract.Data.DATA1, //通常读取DATA1就可以,在具体的ContactsContract.CommonDataKinds.Phone/Email等查到DATA1-DATA15的含义
ContactsContract.Data.DATA2,
… …
ContactsContract.Data.DATA15,
};
读取的方式有两种。
方式一:指定定具体的Uri:
Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawId);
Uri dataUri =Uri.withAppendedPath(rawContactUri,ContactsContract.RawContacts.Data.CONTENT_DIRECTORY);
Cursor cursor = managedQuery( dataUri, INFO_3,null, null, null);
方式二:另一种是利用RawContacts_ID或者Contact_ID,通过Data.CONTENT_URI,具体方式类RawContacts的检索。
Cursor cursor = managedQuery(ContactsContract.Data.CONTENT_URI ,
INFO_3 ,
ContactsContract.Data.RAW_CONTACT_ID + "=?" ,
new String[]{String.valueOf(rawId)} ,
null);
总结一下架构图。实际上Android的联系人提供了多种URI的的查询方式,具体参加Android的reference。
<!--StartFragment -->
相关推荐
1. USIM卡联系人结构 USIM卡上的联系人信息通常遵循ETSI定义的3GPP标准。联系人信息分为多个字段,如Name(姓名)、MSISDN(移动站国际用户识别码,即电话号码)、ANR(自动号码识别)、Email等。每个字段都有特定的...
ANR是USIM卡联系人结构中的一个重要元素,用于存储联系人的其他电话号码,例如家庭电话、办公室电话或移动备用号码。一个联系人条目可以有多个ANR记录,使得用户可以方便地管理多设备或场景下的通信方式。ANR数据...
本项目“数据结构(Java)联系人通讯录”关注的是利用Java编程语言实现一个现实生活中的通讯录系统,这个系统利用排序顺序表作为底层数据结构,支持联系人的增删改查功能,并能保持联系人信息的有序性。 首先,我们...
4. **添加联系人**:此功能涉及创建新的联系人结构并将其插入到数据结构中。用户输入联系人名、电话号码等信息,程序进行有效性检查后保存。 5. **删除联系人**:根据用户提供的姓名或其他标识符查找并删除特定联系...
1. 插入记录模块:创建一个新的联系人结构,获取用户输入的数据,然后将新记录添加到数据结构中,并保存到磁盘文件。 2. 输出功能模块:遍历数据结构,按格式打印出每个联系人的信息,可以有详细模式和简洁模式供...
在 iOS 应用开发中,这种功能对于需要展示复杂联系人结构的应用非常实用,例如社交应用、企业通讯录或者个人信息管理工具。 CLTreeView 的核心特性包括: 1. **多级显示**:CLTreeView 支持显示多级数据,这意味着...
1. 联系人数据存储:支持复式联系人数据的存储,数据条目不少于 1000 条。每个联系人可包括姓名、城市、手机号码、住宅电话号码、办公电话号码、电子邮件、公司、地址、所属群组、备注、添加时间等 11 个字段。 2. ...
3. **内存管理**:在创建和处理联系人结构时,需要进行动态内存分配和释放,以避免内存泄漏。 4. **用户交互**:通过标准输入输出(stdio)进行用户界面的设计,实现增删改查的命令行交互。 5. **错误处理**:编写...
一种常见的方法是使用`struct`或`class`来定义一个联系人结构,包含姓名和电话号码两个属性。例如: ```cpp struct Contact { string name; string phoneNumber; }; ``` - 另外,为了存储多个联系人,你可以...
5. **结构体**:在C语言中,我们可以使用结构体来组合多种类型的数据,如姓名、电话、邮箱等,形成一个完整的联系人结构。结构体使得我们可以作为一个整体来处理联系人信息。 6. **动态内存管理**:为联系人列表...
2. 对每个新插入的联系人,计算其姓名的哈希值,将联系人信息(包括姓名和电话)作为键值对存入散列表。 3. 当查找联系人时,先通过哈希表查找,若查找到则返回电话,否则遍历链表进行查找。 4. 如果链表中的某个...
1. 链表:在通讯录中,我们可以使用链表来存储联系人信息,每个节点包含一个联系人的所有数据。这样,添加新联系人时,只需创建新节点并链接到链表中,无需移动其他元素,方便灵活。同时,删除某个联系人只需改变其...
ContactsContract是Android提供的一个类,它定义了联系人数据的结构和常量,包括联系人表、联系人详情表、群组表等。 3. **查询联系人**: 使用ContentResolver的query()方法可以查询联系人数据。例如,通过`Uri....
通讯录作为日常生活中常见的信息管理工具,它的核心在于如何有效地存储和检索联系人信息。在这个项目中,我们将关注以下几个关键知识点: 1. 数据结构选择:在通讯录系统中,数据结构的选择至关重要。一种常见的...
在实现过程中,开发者通常会利用数据结构(如数组或链表)结合排序算法(如快速排序、归并排序等)对联系人数据进行预处理,然后在界面上以字母索引的形式呈现,用户点击某个字母时,系统会跳转到相应的联系人列表。...
在这个系统中,重点在于如何利用数据结构有效地存储和操作联系人信息。设计目标是通过实践加深对数据结构理论的理解,提高编程解决问题的能力。 在通讯录管理系统中,主要涉及的两种抽象数据类型(ADT)是链表和...
首先,我们要理解电子通讯录的基本功能,包括添加联系人、查找联系人、编辑和删除联系人。这些操作都需要合适的数据结构来支持。最常见的数据结构可能是链表和数组,但更高级的数据结构如哈希表或二叉搜索树可能会...