ContentProvider基础知识

ContentProvider基础知识

1.ContentProvider入门

1.简介

  • 不同程序之间的数据交换,不同app之间的数据共享
  • 学会如何操作数据
  • 学会如何监听数据变化
  • 学会URI,URImatcher,ContentUris的如何使用

2.基本使用

  • A应用,使用ContentProvider的子类进行暴漏数据(前面的五种数据存储的方式),同时给出一个Uri地址
  • B应用,使用ContentReserver进行数据的接收

总之URI是数据连接的桥梁。

3.ContentProvider的简介

  • 四大组件之一
  • 存储和获取数据提供URI接口地址
  • 可以共享数据
  • 系统中常用的视频音频以及电话和短信都有相应的操作
  • 使用的是非execSQL的方式执行查询
  • 一种数据就是一个ContentProvider

4.ContentProvider组织数据的方式

  • 以表的形式组织数据
  • 联系人,通话信息,短信信息,一行就是一条记录
  • _ID是唯一的

5.ContentProvider的使用

  • 自定义,详见1.1.7
  • 系统的

6.ContentProvider方法

抽象类,需要重写它的onCreate()、delete()、getType()、insert()、query()、update()这几个抽象方法。

  • boolean onCreate(),创建后被调用,第一次访问的时候调用
  • insert的用法:Uri insert(Uri uri, ContentValues values),根据Uri插入values中的数据
  • query的用法:select projections from 表 where selection=selectionArgs order by sortOrder
  • delete的用法:public int delete(Uri uri, String selection, String[] selectionArgs),该方法根据Uri删除where条件匹配的所有记录。
  • update的用法:int update(Uri uri, ContentValues values, String selection, String[] selectionArgs),该方法根据Uri修改where条件匹配的全部记录。
  • String getType(Uri uri),返回当前Uri所代表数据的MIME类型。就是一种用来定义除了基本数据类型外的其他类型的数据的一种方法

方法名称

功能描述

public boolean onCreate()

创建ContentProvider时调用

public int delete(Uri uri,String selection,String[] selectionArgs)

根据传入的Uri删除指定条件下的数据

public Uri insert(Uri uri,ContentValues values)

根据传入的Uri插入数据

public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder)

根据传入的Uri查询指定条件下的数据

public int update(Uri uri,ContentVulues values,String selection,String[] selectionArgs)

根据传入的Uri更新指定条件下的数据

public String getType(Uri uri)

用于返回指定Uri代表的MIME类型

注意:在增删改查方法里可以使用嵌入式SQL语句,但是就不如直接使用SQLiteDatabase的增删改查方法直接简单了。

7.ContentProvider主要方法

  • 操作集合:MIME需要以vnd.android.cursor.dir/开头。
  • 操作非集合:如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
案例1
例如,假设一个provider含有列车时刻表,provider的authority是com.example.trains,并且它包含三个表:路线1,路线2,路线3。在URI的响应中,
content://com.example.trains/Line1。指向路线1表,provider返回对应的MIME类型为:
vnd.android.cursor.dir/vnd.example.line1
而content URI:content://com.example.trains/Line2/5。指向路线2表的第5,provider返回的对应的MIME类型为:
vnd.android.cursor.item/vnd.example.line2
案例2
假设一个provider有人员表,该provider的authority是cn.itcast.provider.personprovider。包含一个表:person。
例如:要得到Uri为content://cn.itcast.provider.personprovider/person指向表person,代表所有person记录,那么provider对应的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。
例如:得到id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。

2.自定义的ContentProvider

1.实现过程

  1. 数据源创建就是SQLite的帮助类和实体类等
  2. 自定义类ContentProvider,增删改查+getType以及onCreate方法
  3. 定义URI常量提供ContentResover可以访问到的ContentProvider
  4. 注册,privder标签
<provider
	android:name=cn.itcast.db.PersonDBProvider
	android:authorities=cn.itcast.db.personprovider
              android:exported="true">
</provider>
<!--属性依次为:全限定类名,用于匹配的URI,是否共享数据 -->

3.系统的的ContentProvider

后续补充

4.URI

1.简介:

  • 统一资源定位符,Universal Resource Identifier的简称
  • 每一个ContentProvider都拥有一个公共的URI,这个URI用于表示ContentProvider提供的数据

在AndroidManifest.xml中ContentProvider提供了一个uri的authority部分作为数据的统一接口,就是android:authoritiesContentResolver通过该uri(即Content_URI)访问ContentProvider

2.URL介绍

  • URL是WWW统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
  • http://youke.baidu.com/course/1

3.URI组成

  • 协议://URI标识(注册文件的authority定义的)/路径/ID

  • 实例:
    • content://com.example.codelab.transportationprovider/train:要操作train数据资源所有的记录(如train表)
    • content://com.example.codelab.transportationprovider/train/10:要操作train数据资源中id为10的记录(如train表中id为10的记录)
    • content://com.example.codelab.transportationprovider/train/10/name:要操作train数据资源中id为10的记录的name字段
    • content://com.example.codelab.transportationprovider/train/international:要操作train表下的子表international
    • content://media/external:这个Uri将返回设备上存储的所有图片;
    • content://media/external/images/media/4:某个图片的Uri
    • content://contacts/people:这个Uri将返回设备上的所有联系人信息;

注意:当然要操作的数据不一定来自数据库,也可以是文件等存储方式,如下:

要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name

3.方法

  • parse(str),将str转换成URI地址
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/2")
 Uri uri=Uri.parse("content://com.lxz.app6/studnet/2");
  • List<String> getPathSegments(),获取uri的path,部分存入List

5.解析URI

1.解析URI的

  • 因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。
  • UriMatcher和ContentUris用于解析Uri

2.UriMatcher

  • 用于匹配Uri地址,UriMatcher可以检验当前的Uri地址是不是合法的,合法才可以使用
  • 检验原理:对一个URI的规则起一个编号,如果URI符合这个规则,则返回这个编号,如果在UriMatcher里找不到这个规则,则没有这个编号。规则是int值
  • 使用步骤
    • 初始化UriMatcher
    • 设置需要的URI规则
    • 与已经注册的Uri进行匹配

3.使用UriMatcher步骤

  1. 初始化
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//常量UriMatcher.NO_MATCH表示Uri不匹配时的返回码
  1. 设置需要匹配的Uri规则。

方法名

描述

public void addURI (String authority, String path, int code)

添加一个用于匹配Uri的规则,当匹配成功时则给该Uri一个intcode(匹配码)

public int match (Uri uri)

uri进行匹配

uriMatcher.addURI("com.lxz.app6","studnet",1);
uriMatcher.match(uri);
扩展:
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//添加需要匹配uri(content://cn.itcast.provider.personprovider/person),如果匹配成功就会给该Uri一个匹配码1
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为数字通配符,用了匹配任何数字,*匹配任何字符

匹配码的值需要大于0,否则抛出IllegalArgument异常

  1. 使用match匹配返回匹配ma
switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) { 
   case 1:。。。。。。
    break;
   case 2:。。。。。。。
    break;
   default://不匹配
    break;
}

4.ContentUris类简介

  • ContentUris类用于操作Uri路径后面的ID部分。该类下的方法都为静态方法。
  • 它有两个比较实用的方法:
    • public static Uri withAppendedId (Uri contentUri, long id):用于为路径加上ID部分。
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10); 
//生成后的Uri为:content://cn.itcast.provider.personprovider/person/10

    • public static long parseId (Uri contentUri),该方法用于从路径中获取ID
(id是指数据库中每条记录的唯一标识,即id号。)
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10

6.ContentResover

1.简介

  • 当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成
  • 获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。
  • ContentResolver 类提供了与ContentProvider类相同签名的四个方法,这些方法分别会调用ContenProvider中与之对应的方法,并得到返回的结果。只管调用不管实现。这些方法的第一个参数为Uri,代表要调用的ContentProvider)
假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”)
那么将会对uri为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。

2.使用ContentResover操作数据步骤

  1. 获取ContentResover,ContentResolver resolver = getContentResolver();
  2. 获取ContentProvider的URI标识,

Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");

  1. 使用ContentResolver进行增删改查操作,例如add操作
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
resolver.insert(uri, values);

  1. 监听ContentProvider中数据的变化
  • 在 android 中经常会出现改变数据库内容后再去使用数据库更新的内容,很多人会重新去 query 一遍,但是这样的问题就是程序会特别占内存,而且有可能会忘关 cursor 而导致程序内存未释放等等。
  • 如果应用程序需要实时监听ContentProvider共享的数据是否发生变化,并随着ContentProvider的数据的改变而提供响应。
  • CUD操作都会导致数据的变化,
getContext().getContentResolver().notifyChange(uri,null);
这行代码可用于通知所有注册在该Uri上的监听者:该ContentProvider所共享的数据发生了改变。

3.如何创建监听者,如何往Uri上加监听呢?

  • 内容观察者(ContentObserver)来实现。
  • 内容观察者(ContentObserver)是用来观察指定Uri所代表的数据变化,从而做一些相应的处理,类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。

4.创建监听的步骤

第12步“:


private final class SmsObserver extends ContentObserver{
	public SmsObserver(Handler handler) {
		super(handler);	
	}
	public void onChange(boolean selfChange) {
		Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"),null, null, null, null); 
		while(cursor.moveToNext()){
			StringBuilder sb = new StringBuilder();			sb.append("_id=").append(cursor.getInt(cursor.getColumnIndex("_id")));		sb.append(",address=").append(cursor.getString(cursor.getColumnIndex("address")));	sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));		
            } }}

第3步:ContentProvider通知

public class PersonContentProvider extends ContentProvider {
	public Uri insert(Uri uri, ContentValues values) {
		db.insert("person", "personid", values);
		getContext().getContentResolver().notifyChange(uri, null);
	}
}

第4步:注册监听,第三个参数就是我们创建的监听器

例:
//注册监听
getContentResolver().registerContentObserver(Uri.parse("content://sms"),
        		true,
//true表示只要发出通知的Uri以方法第一个参数开头都能被监听到,否则监听uri必须与发出通知的uri完全匹配才能被监听到
                                           new PersonObserver(new Handler()));
//监听类
public class PersonObserver extends ContentObserver{
	public PersonObserver(Handler handler) {
		super(handler);
 	}
	public void onChange(boolean selfChange) {
	    //此处可以进行相应的业务处理
	}
}

5.取消注册

public final void unregisterContentObserver(ContentObserver observer)
功能:取消对给定Uri的观察

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android的系统架构 6 一、应用程序 6 二、应用程序框架 6 三、Android Runtime 7 四、系统库 7 五、Linux 内核 8 Webkit浏览器引擎简介 9 Dalvik虚拟机简介 11 什么是Dalvik虚拟机 11 Dalvik和Android系统 11 Dalvik虚拟机的主要特征 12 Android应用开发和Dalvik虚拟机 15 Activity生命周期 16 一、Activity栈 16 二、Activity的4种状态 16 三、Activity的生命周期 17 四、实例说明 18 Android控件的继承关系 22 一、View与ViewGroup关系 22 二、各控件的继承关系 23 界面布局 25 LinearLayout(线性布局) 25 TableLayout(表格布局) 28 RelativeLayout(相对布局) 31 AbsoluteLayout(绝对布局) 34 FrameLayout(框架布局) 34 Toast 36 Notification 38 对话框 42 一、带三个按钮的对话框 42 二、简单列表对话框、单选列表对话框、多选列表对话框 44 三、水平进度对话框和圆形进度对话框 47 四、自定义对话框 49 Menu菜单 52 选项菜单 52 上下文菜单 53 三、子菜单 54 4种响应菜单项单击事件的方式 56 显示和编辑文本的控件 57 TextView 57 CheckedTextView 60 EditText 60 ExtraEditText 61 AutoComplteteTextView、MultiAutoCompleteTextView (自动完成输入内容) 61 Button 63 ImageButton 65 ZoomButton 65 日期和时间控件 66 DatePicker、TimePicker 66 AnalogClock、DigitalClock 68 单选框、复选框、开关状态按钮 69 单项选择(RadioGroup、RadioButton) 69 复选框(CheckBox) 71 开关状态按钮(ToggleButton) 73 下拉列表框Spinner 74 ScrollView、HorizontalScrollView 77 垂直滚动(ScrollView) 77 水平滚动(HorizontalScrollView) 78 两个方向均可滚动 78 TabHost 79 ProgressBar、SeekBar、RatingBar 81 进度条(ProgressBar) 81 拖动条(SeekBar) 83 评分组件(RatingBar) 86 GridView、Gallery和ImageSwitcher 88 GridView 88 Gallery和ImageSwitcher 91 ListView 94 一、普通的ListView 94 可以单选和多选的ListView 95 使用SimpleAdapter建立复杂的列表项 97 自定义Adapter来建立复杂的列表项 99 动态添加、删除ListView列表项 102 改变ListView列表项选中状态的背景颜色 102 可展开的列表组件 102 数据的存取 103 SharePreferences 6.1 103 文件的存储6.2 103 SQLite数据库6.4 103 ContentProviderContentResolver 6.5 105 Intent 106 用Intent启动Activity,并在Activity之间传递数据 106 调用其他应用程序中的Activity(打电话、浏览网页、发Email等) 109 接收和发送广播 113 接收系统广播 113 在自己的应用程序中发送广播 117 Android服务 118 系统服务 8.2 118 时间服务 8.3 118 跨进程访问 8.4 118 网络 119 图形、音频、视频 120 图形 10.1 120 音频、视频 10.2 120 2D动画 121 帧动画 121 补间动画 121 OpenGL ES编程 122 Android支持的各种资源 123 窗口小部件(App Widget) 124 NDK编程 125
内容简介   《Android基础教程(第3版·修订版)》是一部关于Android开发的基础教程,采用Pragmatic系列图书一贯由浅入深、循序渐进的方式讲解了Android程序设计的核心概念和技术。书中不仅结合数独游戏开发案例形象生动地讲解了Android生命周期、用户界面、2D图形、多媒体,以及本地数据存储等基础知识,而且通过“Hello, Android”项目深入探讨了外部通信、基于位置的服务、内置SQLite数据库、3D图形、多点触控、小部件、兼容性测试,以及如何向AndroidMarket发布应用程序等内容。前13章章尾均有“快速阅读指南”,你无需按照顺序阅读该章,即可迅速找到所需信息,并高效地完成工作。   《Android基础教程(第3版·修订版)》适合所有移动开发人员学习参考。 目录 第一部分 Android简介 第1章 快速入门 1.1 安装工具 1.1.1 Java 5.0+ 1.1.2 Eclipse 3 1.1.3 AndroidSDK启动程序软件包 1.1.4 AndroidSDK组件 1.1.5 Eclipse插件 1.2 创建第一个程序 1.3 在模拟器上运行程序 1.3.1 创建一个AVD 1.3.2 再试一次 1.4 在手机上运行程序 1.5 快速阅读指南 第2章 基本概念 2.1 Android的系统架构 2.1.1 Linux内核 2.1.2 本机库 2.1.3 Android运行时 2.1.4 应用程序框架 2.1.5 应用程序和小部件 2.2 它还活着 2.2.1 进程不等于应用程序 2.2.2 应用程序生命周期 2.3 构建块 2.3.1 活动 2.3.2 意图 2.3.3 服务 2.3.4 内容提供者 2.4 使用资源 2.5 安全性 2.6 快速阅读指南 第二部分 Android基础知识 第3章 设计用户界面 3.1 数独游戏简介 3.2 声明性设计 3.3 创建启动界面 3.4 使用替代资源 3.5 实现About对话框 3.6 应用主题 3.7 添加菜单 3.8 添加设置 3.9 开始新游戏 3.1 调试程序 3.10.1 利用日志消息调试程序 3.10.2 利用调试器调试程序 3.11 退出游戏 3.12 快速阅读指南 第4章 绘制2D图形 4.1 Android图形基础 4.1.1 Color类 4.1.2 Paint类 4.1.3 Canvas类 4.1.4 Path类 4.1.5 Drawable类 4.2 在数独程序中添加图形 4.2.1 开始游戏 4.2.2 定义Game类 4.2.3 定义PuzzleView类 4.2.4 绘制游戏盘面 4.2.5 绘制数字 4.3 处理输入 4.3.1 定义和更新选定区域 4.3.2 输入数字 4.3.3 增加提示 4.3.4 抖动屏幕 4.4 其他问题 4.4.1 创建软键盘 4.4.2 实现游戏逻辑 4.4.3 其他功能 4.5 更多改进 4.6 快速阅读指南 第5章 多媒体 5.1 播放音频 5.2 播放视频 5.3 为数独游戏配上音乐 5.4 快速阅读指南 第6章 存储本地数据 6.1 为数独游戏添加选项 6.2 继续玩前一个游戏 6.3 记住当前位置 6.4 访问内部文件系统 6.5 访问SD卡 6.6 快速阅读指南 第三部分 高级主题 第7章 互联的世界 7.1 通过意图实现浏览 7.2 利用视图打开网页 7.3 JavaScript与Java通信 7.4 使用Web服务 7.5 快速阅读指南 第8章 定位与环境感知 8.1 位置,位置,位置 8.1.1 我在哪里 8.1.2 更新位置 8.1.3 模拟说明 8.2 充分利用传感器 8.2.1 了解传感器 8.2.2 解析传感器的读数 8.2.3 模拟说明 8.3 地图功能 8.3.1 嵌入MapView 8.3.2 准备就绪 8.3.3 模拟说明 8.4 快速阅读指南 第9章 SQL实战 9.1 SQLite简介 9.2 SQL基础 9.2.1 DDL语句 9.2.2 修改语句 9.2.3 查询语句 9.3 你好,数据库 9.3.1 使用SQLiteOpenHelper 9.3.2 定义主程序 9.3.3 添加一行 9.3.4 运行一个查询 9.3.5 显示查询结果 9.4 数据绑定 9.5 使用ContentProvider 9.5.1 更改主程序 9.5.2 添加一行 9.5.3 运行一个查询 9.6 实现ContentProvider 9.7 快速阅读指南 第10 章 利用OpenGL实现3D图形 10.1 理解3D图形 10.2 OpenGL简介 10.3 构建一个OpenGL程序 10.4 渲染场景 10.5 构建一个模型 10.6 光线、相机 10.7 动作 10.8 应用纹理 10.9 透明效果 10.1 测量平滑度 10.11 快速阅读指南 第四部分 下一代产品 第11章 多点触控 11.1 多点触控概述 11.2 创建触控示例 11.3 了解触控事件 11.4 设置图像变换 11.5 实现拖动动作 11.6 实现捏压缩放动作 11.6.1 两个点之间的距离 11.6.2 两个点的中点 11.7 快速阅读指南 第12章 主界面 12.1 Hello,Widget 12.1.1 创建第一个小部件程序 12.1.2 调用所有小部件 12.1.3 拉伸以适合屏幕尺寸 12.1.4 使用和扩展 12.1.5 运行小部件 12.1.6 最新进展 12.1.7 快乐之旅 12.2 动态壁纸 12.2.1 创建壁纸项目 12.2.2 服务简介 12.2.3 创建一个绘图引擎 12.2.4 重用OpenGL代码 12.2.5 创建和销毁引擎 12.2.6 管理Surface 12.2.7 可视化壁纸 12.2.8 响应用户的输入 12.3 快速阅读指南 第13章 一次编写,到处测试 13.1 启动模拟器 13.2 创建适用于多个版本的程序 13.3 AndroidAPI的发展 13.4 大量错误 13.5 各种屏幕尺寸 13.6 在SD卡上安装程序 13.7 快速阅读指南 第14章 发布到AndroidMarket 14.1 准备工作 14.2 签名 14.3 发布 14.4 更新 14.5 结语 第五部分 附录 附录A Java与Android:语言及其API 附录B 参考书目

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简单点了

谢谢大佬

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值