(一)、SQLiteDatabase和SQLiteOpenHelper的封装:
(二)、ListView分页显示数据:
目标:能完成以下功能——访问本地网址,实现异步加载数据,解析json数据,分页显示在ListView组件中。
二、ContentProvider简介:
(一)、引入:
数据库在Android当中是私有的,不能将数据库设为WORLD_READABLE,每个数据库都只能创建它的包访问。这意味着只有创建这个数据库的应用程序才可访问它。也就是说不能跨越进程和包的边界,直接访问别的应用程序的数据库。那么如何在应用程序间交换数据呢? 如果需要在进程间传递数据,可以使用ContentProvider来实现。
(二)、ContentProvider的功能和意义:
为了在应用程序之间交换数据,Android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API。当一个应用程序需要把自己的数据暴露给其他应用程序使用时,该应用程序可以通过提供ContentProvider来实现;而其他应用程序需要使用这些数据时,可以通过ContentResolver来操作ContentProvider暴露的数据。
一旦某个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作被暴露的内部数据,包括增加数据、删除数据、修改数据、查询数据等。
虽然大部分使用ContentProvider操作的数据都来自于数据库,但是也可以来自于文件、SharedPreferences、XML或网络等其他存储方式。
(三)、核心类:
1、ContentProvider:(A应用暴露数据)
2、ContentResolver:(操作A应用所暴露的数据)
3、 Uri:Uri是ContentResolver和ContentProvider进行数据交换的标识。
【备注:】URI、URL、URN的区别:
也就是说,URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。
总结一下:URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,所以,是绝对的。
(四)、系统内置的预定义ContentProvider:
1、Contacts:获取、修改、保存联系人的信息;
2、MediaStore:访问声音、视频、图片等多媒体文件;
3、CallLog :查看或更新通话记录;
4、Browser:读取或修改浏览历史、网络搜索、书签;
5、Setting:查看和获取蓝牙设置、铃声设置等设备首选项。
6、SMS:短信
三、使用ContentResolver 管理联系人:
(一)、 使用ContentResolver 操作数据的步骤:
1、调用Context的getContentResolver()方法获得ContentResolver 对象;
2、调用使用ContentResolver 的insert()、delete()、update()、query()方法操作数据。
参数解释:
String where:表示带有占位符的where子句组成的字符串;
String[] whereArgs:表示替换where参数中占位符后的数据组成的字符串数组;
String sortOrder:表示select语句中的order by子句组成的字符串;
String[] projection:表示select语句中需要查询的所有的字段组成的字符串数组。
ContentValues values:是由数据库中表字段和往该字段中放置的数据所组成的键值对对象。
【备注:】以上四个方法的参数分别是2、3、4、5个。
(二)、 联系人管理中ContentProvider的几个Uri:
1、联系人的Uri==> content://com.android.contacts/contacts 和 content://com.android.contacts/raw_contacts
2、电话号码的Uri==> content://com.android.contacts/data/phones
3、EMAIL的URI==> content://com.android.contacts/data/emails
不过为了方便记忆,系统中提供了以下常量来替代以上的Uri字符串。
(三)、示例代码1——查看通讯录中的联系人姓名、id、电话、Email等信息:
publicstatic List<Map<String, Object>> selectContactsMsg(
ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse(uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);
// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts
.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts
.getColumnIndex("display_name"));
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);
// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(
Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());
// 以下开始或许Email信息
Cursor cursor_emails = resolver.query(
Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());
// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}
(四)、示例代码2——实现新添加通讯录信息:
// 以下方法是利用常量值所写的插入联系人的方法。如果希望封装成方法,再增加一个Map集合的参数,用来传入信息即可。
publicvoid insertContacts(ContentValues values, ContentResolver resolver) {
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(
ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
// 往data表入姓名数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
"王向军");
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
"王向军");
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
// 往data表入电话数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "13520551441");
values.put(ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
// 往data表入Email数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Email.DATA,
"2372375@qq.com");
values.put(ContactsContract.CommonDataKinds.Email.TYPE,
ContactsContract.CommonDataKinds.Email.TYPE_WORK);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
}
(五)、封装ContentResolver操作系统联系人的工具类ContactsResolverHelper:【重要】
publicclass ContactsResolverHelper {
/*
* / 以下代码是插入新联系人的子过程。其中第三个参数:List集合表示要插入到通讯录中的新数据(该集合中有三个值,分别是:姓名、电话、email)。
*/
publicvoid insertContacts(ContentResolver resolver, ContentValues values,
List<String> list) {
String uri_rawcontacts = "content://com.android.contacts/raw_contacts";
String uri_data = "content://com.android.contacts/data";
Uri uri = Uri.parse(uri_contacts);
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(Uri.parse(uri_rawcontacts), values);
long contact_id = ContentUris.parseId(rawContactUri);
// 往data表中插入一条用户的名称信息
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/name");
values.put("data1", list.get(0));
values.put("data2", list.get(0));
resolver.insert(uri_data, values);
// 往data表中插入电话信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/phone_v2");
values.put("data1", list.get(1));
values.put("data2", 2);// 2,Phone.TYPE_MOBILE ,表示手机号码
resolver.insert(uri_data, values);
// 往data表中插入Email信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/email_v2");
values.put("data1", list.get(2));
values.put("data2", 2);// 2,Email.TYPE_WORK , 表示工作用Email号码
resolver.insert(uri_data, values);
}
// 以下代码是删除联系人信息的方法。
publicstaticint deleteContacts(ContentResolver resolver, String where,
String[] whereArgs) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.delete(Uri.parse(uri_contacts), where, whereArgs);
}
// 以下代码是查询联系人信息的方法。
publicstatic Cursor selectContactsName(ContentResolver resolver,
String[] projection, String where, String[] whereArgs,
String sortOrder) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.query(Uri.parse(uri_contacts), projection, where,
whereArgs, sortOrder);
}
publicstatic List<Map<String, Object>> selectContactsMsg(
ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse(uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);
// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts
.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts
.getColumnIndex("display_name"));
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);
// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(
Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());
// 以下开始或许Email信息
Cursor cursor_emails = resolver.query(
Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());
// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}
// 以下代码是更新联系人姓名的方法。
publicstaticint updateContactsName(ContentValues values,
ContentResolver resolver, String oldName, String newName) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_data = "content://com.android.contacts/data";
// 先更新raw_contacts表中的联系人姓名,共有四列需要更新
values.put("display_name", newName);
values.put("display_name_alt", newName);
values.put("sort_key", newName);
values.put("sort_key_alt", newName);
int count1 = resolver.update(Uri.parse(uri_contacts), values,
"display_name=?", new String[] { oldName });
// 再更新data表中联系人的姓名,共有两列
values.clear();
values.put("data1", newName);
values.put("data2", newName);
int count2 = resolver.update(Uri.parse(uri_contacts_data), values,
"data1=? and mimetype_id=?", new String[] { oldName, "7" });
// 返回2,则说明六项都被更新。如果只返回1,则说明没有修改完全
return count1 + count2;
}
}
(一)、Android系统管理联系人的Uri如下:
【数据库中主要字段:】
(二)、Android为多媒体提供的ContentProvider的Uri如下:
图片数据库字段:20个
_id ,_data,_size,_display_name,mime_type,title,date_added,date_modified,description,picasa_id,isprivate,latitude,longitude,datetaken,orientation,mini_thumb_magic,bucket_id,bucket_display_name,width,height
音频数据字段:29个
_id,_data,_display_name,_size,mime_type,date_added,is_drm,date_modified,title,title_key,duration,artist_id,composer,album_id,track,year,is_ringtone,is_music,is_alarm,is_notification,is_podcast,bookmark,album_artist,artist_id:1,artist_key,artist,album_id:1,album_key,album,
视频数据字段:27个
_id,_data,_display_name,_size,mime_type,date_added,date_modified,title,duration,artist,album,resolution,description,isprivate,tags,category,language,mini_thumb_data,latitude,longitude,datetaken,mini_thumb_magic,bucket_id,bucket_display_name,bookmark,width,height,
【数据库中主要字段:】
(三)、短信Uri:
【数据库中主要字段:】
(四)、通话记录Uri:
1、完善代码“ContentResolver管理联系人”,增加添加联系人功能,增加删除联系人功能。
2、利用ContentResolver制作管理SDCard上的多媒体文件管理器。
3、利用ContentResolver+AutoCompleteTextView实现自动补全联系人姓名。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务