数据存储与访问

Download Report

Transcript 数据存储与访问

基于Android的移
动应用开发
数据存储与访问
数据存储与访问
Android 提供的方法
◦ Shared Preferences
◦ Store private primitive data in key-value pairs.
◦ Internal Storage
◦ Store private data on the device memory.
◦ External Storage
◦ Store public data on the shared external storage.
◦ SQLite Databases
◦ Store structured data in a private database.
◦ Network Connection
◦ Store data on the web with your own network server.
◦ Content provider
◦ expose your private data to other applications
数据存储与访问
掌握SharedPreferences的使用方法
掌握各种文件存储的区别与适用情况
了解SQLite数据库的特点和体系结构
掌握SQLite数据库的建立和操作方法
理解ContentProvider的用途和原理
掌握ContentProvider的创建与使用方法
3
SharedPreferences
◦ SharedPreferences是一种轻量级的数据保存方式
◦ 通过SharedPreferences可以将NVP(Name/Value
Pair,名称/值对)保存在Android的文件系统中,
而且SharedPreferences完全屏蔽的对文件系统的
操作过程
◦ 开发人员仅是通过调用SharedPreferences对NVP
进行保存和读取
4
SharedPreferences
◦ SharedPreferences不仅能够保存数据,还能够实
现不同应用程序间的数据共享
◦ SharedPreferences支持三种访问模式
◦
◦
◦
私有(MODE_PRIVATE):仅有创建程序有权限对其进行读取或写入
全局读(MODE_WORLD_READABLE):不仅创建程序可以对其进行
读取或写入,其他应用程序也读取操作的权限,但没有写入操作的
权限
全局写(MODE_WORLD_WRITEABLE):创建程序和其他程序都可以
对其进行写入操作,但没有读取的权限
5
SharedPreferences
◦ 在使用SharedPreferences前,先定义
SharedPreferences的访问模式
◦ 下面的代码将访问模式定义为私有模式
public static int MODE = MODE_PRIVATE;
◦ 有的时候需要将SharedPreferences的访问模式设定为
既可以全局读,也可以全局写,这样就需要将两种
模式写成下面的方式
public static int MODE = Context.MODE_WORLD_READABLE +
Context.MODE_WORLD_WRITEABLE;
6
SharedPreferences
在应用中获得首选项的方法
◦ getSharedPreferences()
◦ 一个activity可以使用多个首选项文件,以第一个参数为标识
◦ getPreferences()
◦ 一个activity只有一个首选项文件
SharedPreferences
◦ 定义SharedPreferences的名称,这个名称与在
Android文件系统中保存的文件同名。因此,只要
具有相同的SharedPreferences名称的NVP内容,都
会保存在同一个文件中
public static final String PREFERENCE_NAME = "SaveSetting";
◦ 为了可以使用SharedPreferences,需要将访问模式
和SharedPreferences名称作为参数,传递到
getSharedPreferences()函数,并获取到
SharedPreferences对象
SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCE_NAME,
MODE);
或者
SharedPreferences sharedPreferences= getPreferences(MODE);
8
SharedPreferences
◦ 在获取到SharedPreferences对象后,则可以通过
SharedPreferences.Editor类对SharedPreferences进行
修改,最后调用commit()函数保存修改内容
◦ SharedPreferences广泛支持各种基本数据类型,包
括整型、布尔型、浮点型和长型等等
1.
2.
3.
4.
5.
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("Name", "Tom");
editor.putInt("Age", 20);
editor.putFloat(“Height”,1.8 );
editor.commit();
9
SharedPreferences
◦ 如果需要从已经保存的SharedPreferences中读取数据,
同样是调用getSharedPreferences()函数,并在函数的
第1个参数中指明需要访问的SharedPreferences名称,
最后通过get<Type>()函数获取保存在
SharedPreferences中的NVP
1. SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCE_NAME,
MODE);
2. String name = sharedPreferences.getString("Name","Default Name");
3. int age = sharedPreferences.getInt("Age", 20);
4. float height = sharedPreferences.getFloat("Height",1.7);
◦ get<Type>()函数的第1个参数是NVP的名称
◦ 第2个参数是在无法获取到数值的时候使用的缺省值
10
SharedPreferences
◦ 访问其他应用程序的SharedPreferences必须满足三个
条件
◦
◦
◦
共享者需要将SharedPreferences的访问模式设置为全局读或全局写
访问者需要知道共享者的包名称和SharedPreferences的名称,以通过Context
获得SharedPreferences对象,调用createPackageContext()方法
访问者需要确切知道每个数据的名称和数据类型,用以正确读取数据
11
SharedPreferences-TodoList4
TodoList活动中的实例状态
◦ 是否是一个添加的新数据项
◦ 文本框中的文本是什么
◦ 当前所选择的数据项是什么
SharedPreferences-TodoList4
步骤1:添加作为首选项键的字符串变量
private static final String TEXT_ENTRY_KEY = “TEXT_ENTRY_KEY”
private static final String ADDING_ITEM_KEY =
“ADDING_ITEM_KEY”
private static final String SELECT_ITEM_KEY =
“SELECT_ITEM_KEY”
SharedPreferences-TodoList4
步骤2:重写onPause方法
protected void onPause(){
super.onPause();
//获得首选项对象
SharedPreferences uiState = getPreferences(MODE_PRIVATE);
//获得首选项编辑器
SharedPreferences.Editor editor = uiState.edit();
//添加UI状态首选项的值
editor.putString(TEXT_ENTRY_KEY, myEditText.getText().toString());
editor.putBoolean(ADDING_ITEM_KEY, addingNew);
//提交首选项
editor.commit();
}
SharedPreferences-TodoList4
步骤3:编写restoreUIState方法,并在onCreate方法
中调用该方法。
private void restoreUIState() {
SharedPreferences settings = getPreferences(MODE_PRIVATE);
//读取UI值
String text = settings.getString(TEXT_ENTRY_KEY, "");
Boolean adding = settings.getBoolean(ADDING_ITEM_KEY, false);
//将UI恢复到前一状态
if(adding){
addNewItem();
myEditText.setText(text);
}
}
SharedPreferences-TodoList4
步骤4:使用onSaveInstanceState /
onRestoreInstanceState机制来记录已选择的数据项索引
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putInt(SELECT_ITEM_KEY,
myListView.getSelectedItemPosition());
super.onSaveInstanceState(savedInstanceState);
}
SharedPreferences-TodoList4
步骤4:使用onSaveInstanceState /
onRestoreInstanceState机制来记录已选择的数据项索引
public void onRestoreInstanceState(Bundle savedInstanceState){
int pos = -1;
if(savedInstanceState != null){
if(savedInstanceState.containsKey(SELECT_ITEM_KEY)){
pos = savedInstanceState.getInt(SELECT_ITEM_KEY, -1);
}
}
myListView.setSelection(pos);
}
SharedPreferences-TodoList4
运行效果:
文件存储
Android使用的是基于Linux的文件系统,程序开发人员可以建立和
访问程序自身的私有文件,也可以访问保存在资源目录中的原始文
件和XML文件,还可以在SD卡等外部存储设备中保存文件
19
文件存储
Android系统允许应用程序创建仅能够自身访问
的私有文件
Android系统不仅支持标准Java的IO类和方法,
还提供了能够简化读写流式文件过程的函数
主要介绍的两个函数
◦
◦
openFileOutput()
openFileInput()
20
文件存储
openFileOutput()函数
openFileOutput()函数为写入数据做准备而打开的应用程序私文件,如果
指定的文件不存在,则创建一个新的文件
openFileOutput()函数的语法格式如下
◦
◦
◦
第1个参数是文件名称,这个参数不可以包含描述路径的斜杠
第2个参数是操作模式
函数的返回值是FileOutputStream类型
public FileOutputStream openFileOutput(String name, int mode)
21
文件存储
openFileOutput()函数
◦
Android系统支持四种文件操作模式
模式
说明
MODE_PRIVATE
私有模式,缺省模式,文件仅
能够被文件创建程序访问,或
具有相同UID的程序访问。
MODE_APPEND
追加模式,如果文件已经存在,
则在文件的结尾处添加新数据。
MODE_WORLD_READABLE
全局读模式,允许任何程序读
取私有文件。
全局写模式,允许任何程序写
入私有文件。
MODE_WORLD_WRITEABLE
22
文件存储
openFileOutput()函数
◦ 使用openFileOutput()函数建立新文件的示例代码如下
1.
2.
3.
4.
5.
6.
String FILE_NAME = "fileDemo.txt";
FileOutputStream fos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE)
String text = “Some data”;
fos.write(text.getBytes());
fos.flush();
fos.close();
◦
◦
◦
◦
◦
第1行代码定义了建立文件的名称fileDemo.txt
第2行代码使用openFileOutput()函数以私有模式建立文件
第4行代码调用write()函数将数据写入文件
第5行代码调用flush()函数将所有剩余的数据写入文件
第6行代码调用close()函数关闭FileOutputStream
23
文件存储
openFileOutput()函数
◦
◦
为了提高文件系统的性能,一般调用write()函数时,如果写入的数据
量较小,系统会把数据保存在数据缓冲区中,等数据量累积到一定程
度时再一次性的写入文件中
由上可知,在调用close()函数关闭文件前,务必要调用flush()函数,将
缓冲区内所有的数据写入文件
24
文件存储
openFileInput()函数
◦
◦
openFileInput()函数为读取数据做准备而打开应用程序私文件
openFileInput()函数的语法格式如下
◦
参数为文件名称,不允许包含描述路径的斜杠
public FileInputStream openFileInput (String name)
25
文件存储
openFileInput()函数
◦ 使用openFileInput ()函数打开已有文件的示例代码如下
1.
2.
3.
4.
5.
6.
String FILE_NAME = "fileDemo.txt";
FileInputStream fis = openFileInput(FILE_NAME);
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1){
}
◦ 上面的两部分代码在实际使用过程中会遇到错误提示,
因为文件操作可能会遇到各种问题而最终导致操作失败,
因此代码应该使用try/catch捕获可能产生的异常
26
文件存储
资源文件
◦ 程序开发人员可以将程序开发阶段已经准备好的
原始格式文件和XML文件分别存放在/res/raw和
/res/xml目录下,供应用程序在运行时进行访问
◦ 原始格式文件可以是任何格式的文件,例如视频
格式文件、音频格式文件、图像文件和数据文件
等等,在应用程序编译和打包时,/res/raw目录下
的所有文件都会保留原有格式不变
◦ /res/xml目录下的XML文件,一般用来保存格式化
的数据,在应用程序编译和打包时会将XML文件
转换为高效的二进制格式,应用程序运行时会以
特殊的方式进行访问
27
文件存储
res/raw文件夹下的资源文件读取
调用Resource对象上的openRawResource方法,传
入文件名(不带扩展名)作为R.raw类的变量名
1. Resource myRes = getResource();
2. InputStream myFile = myRes.openRawSource(R.raw.myfilename);
28
文件存储
◦ /res/xml目录下的XML文件会转换为一种高效的二进
制格式
◦ 说明如何在程序运行时读取/res/xml目录下的XML文
件
◦
首先在/res/xml目录下创建一个名为people.xml的文件
◦
XML文件定义了多个<person>元素,每个<person>元素都包含三个属性name、age和height,
分别表示姓名、年龄和身高
◦ /res/xml/people.xml文件代码如下
1. <people>
2.
<person name="李某某" age="21" height="1.81" />
3.
<person name="王某某" age="25" height="1.76" />
4.
<person name="张某某" age="20" height="1.69" />
5. </people>
29
文件存储
◦ 读取XML格式文件
◦
首先通过调用资源对象的getXml()函数,获取到XML解析器XmlPullParser
◦
XmlPullParser是Android平台标准的XML解析器,这项技术来自一个开源的XML解析API项目
XMLPULL
◦ ResourceFileDemo示例中关于读取XML文件的核心代
码如下
1. XmlPullParser parser = resources.getXml(R.xml.people);
2. String msg = "";
3. try {
4.
while (parser.next() != XmlPullParser.END_DOCUMENT) {
5.
String people = parser.getName();
6.
String name = null;
30
文件存储
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
String age = null;
String height = null;
if ((people != null) && people.equals("person")) {
int count = parser.getAttributeCount();
for (int i = 0; i < count; i++) {
String attrName = parser.getAttributeName(i);
String attrValue = parser.getAttributeValue(i);
if ((attrName != null) && attrName.equals("name")) {
name = attrValue;
} else if ((attrName != null) && attrName.equals("age"))
{
17.
18.
age = attrValue;
} else if ((attrName != null) &&
attrName.equals("height")) {
19.
20.
21.
22.
23.
height = attrValue;
}
}
if ((name != null) && (age != null) && (height != null)) {
msg += "姓名:"+name+",年龄:"+age+",身高:"+height+"\n";
31
文件存储
24.
}
25.
}
26.
}
27. } catch (Exception e) {
28.
Log.e("ResourceFileDemo", e.getMessage(), e);
29. }
30. displayView.setText(msg);
◦
◦
◦
◦
◦
◦
◦
第1行代码通过资源对象的getXml()函数获取到XML解析器
第4行代码的parser.next()方法可以获取到高等级的解析事件,并
通过对比确定事件类型
第5行代码使用getName()函数获得元素的名称
第10行代码使用getAttributeCount()函数获取元素的属性数量
第12行代码通过getAttributeName()函数得到属性名称
第14行到第19行代码通过分析属性名获取到正确的属性值
第23行代码将属性值整理成需要显示的信息
32
文件存储
◦ XmlPullParser的XML事件类型
事件类型
START_TAG
TEXT
END_TAG
END_DOCUMENT
说明
读取到标签开始标志
读取文本内容
读取到标签结束标志
文档末尾
33
文件存储
Android 文件管理
◦
public boolean deleteFile (String name)
◦
◦
使用户能够删除由当前应用程序所创建的文件
public String[] fileList ()
◦
返回一个字符串列表,包含了当前应用程序所创建的所有文件
34
数据库存储
SQLite是一种流行的关系数据库管理系统
◦ 开源、兼容标准、轻量级、单层
被实现为一个简洁的C库,作为Android软件栈的一部分
列定义中使用一种松散类型的方法,不要求一列中的所有值都是同
一种类型
http://www.sqlite.org
35
数据库存储
通过创建一个辅助类来简化数据库交互是一
种很好的做法
一般将所有对数据库的操作都封装在一个类
中,因此只要调用这个类,就可以完成对数
据库的添加、更新、删除和查询等操作
36
数据库存储
下面内容是MyDBAdapter类的部分代码,封装了
数据库的建立、打开和关闭等操作
public class MyDBAdapter {
private static final String DATABASE_NAME = "myDatabase.db";
private static final String DATABASE_TABLE = "mainTable";
private static final int DATABASE_VERSION = 1;
// where子句中使用的索引(键)列的名称.
public static final String KEY_ID="_id";
// 列名.
public static final String KEY_NAME="name";
public static final int NAME_COLUMN = 1;
// 创建数据库的SQL语句.
private static final String DATABASE_CREATE = "create table " +
DATABASE_TABLE + " (" + KEY_ID +
" integer primary key autoincrement, " +
KEY_NAME + " text not null);";
37
数据库存储
// 用来保存数据库实例的 变量
private SQLiteDatabase db;
// 使用数据库的应用程序上下文.
private final Context context;
// 数据库的打开/升级helper
private myDbHelper dbHelper;
public MyDBAdapter(Context _context) { //构造函数
context = _context;
dbHelper = new myDbHelper(context, DATABASE_NAME, null,
DATABASE_VERSION);
}
public MyDBAdapter open() throws SQLException { //打开数据库
db = dbHelper.getWritableDatabase();
return this;
}
public void close() { //关闭数据库
db.close();
}
38
数据库存储
public int insertEntry(MyObject _myObject) {
// TODO: 创建一个新的ContentValues来表示行,
// 并把它插入到数据库中
return index;
}
public boolean removeEntry(long _rowIndex) {
return db.delete(DATABASE_TABLE, KEY_ID + "=" + _rowIndex, null) > 0;
}
public Cursor getAllEntries () {
return db.query(DATABASE_TABLE, new String[] {KEY_ID, KEY_NAME},
null, null, null, null, null);
}
public MyObject getEntry(long _rowIndex) {
// TODO: 返回指向一个行的游标,
// 并使用该行的值来填充MyObject的一个实例
return objectInstance;
}
39
数据库存储
public boolean updateEntry(long _rowIndex, MyObject _myObject) {
// TODO: 基于新对象创建一个新的ContentValues,
// 并使用它来更新数据库中的一个行.
return true;
}
private static class myDbHelper extends SQLiteOpenHelper {
public myDbHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
// 当磁盘上没有数据库时调用,helper类需要创建一个新的数据库
@Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE);
}
40
数据库存储
// 当数据库版本不匹配时调用,也就是说,磁盘上的数据库需要升级到当前版本
@Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion) {
// Log the version upgrade.
Log.w("TaskDBAdapter", "Upgrading from version " +
_oldVersion + " to " +
_newVersion + ", which will destroy all old data");
// 将现有的数据库升级到新版本
// 通过比较_oldVersion和_newVersion的值可以处理多个旧版本
// 最简单的情况就是删除旧表,创建新表.
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Create a new one.
onCreate(_db);
}
}
}
41
数据库存储
◦ SQLiteOpenHelper是一个抽象类,用来实现创建、打开和升级数据库的最佳实
践模式
◦ 调用getReadableDatabase或者getWriteableDatabase来打开和返回一个可读/可写
的底层数据库实例
◦ 由于磁盘空间或者权限问题,对getWriteableDatabase的调用可能失败,较好的
做法是提供一个对getReadableDatabase方法的回退
42
数据库存储
dbHelper = new myDbHelper(context, DATABASE_NAME, null,
DATABASE_VERSION);
SQLiteDatabase db;
try {
db = dbHelper.getWritableDatabase();
}
catch (SQLiteException ex){
db = dbHelper.getReadableDatabase();
}
43
数据库存储
如果程序开发人员不希望使用SQLiteOpenHelper
类,同样可以直接创建数据库
◦ 首先调用openOrCreateDatabases()函数创建数据库对
象
◦ 然后执行SQL命令建立数据库中的表和直接的关系
◦ 示例代码如下
private static final String DATABASE_NAME = "myDatabase.db";
private static final String DATABASE_TABLE = "mainTable";
private static final String DATABASE_CREATE =
"create table " + DATABASE_TABLE + " ( _id integer primary key autoincrement," +
"column_one text not null);";
SQLiteDatabase myDatabase;
private void createDatabase() {
myDatabase = openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE,
null);
myDatabase.execSQL(DATABASE_CREATE);
}
44
数据库存储
数据操作
◦ 数据操作是指对数据的添加、删除、查找和更新的
操作
◦ 可以通过执行SQL命令完成数据操作,execSQL()
方法
◦ 但推荐使用Android提供的专用类和方法,这些类和
方法更加简洁、易用
45
数据库存储
数据操作
◦ SQLiteDatabase类的公共函数insert()、delete()、
update()和query(),封装了执行的添加、删除、更
新和查询功能的SQL命令
◦ 下面分别介绍如何使用SQLiteDatabase类的公共函
数,完成数据的添加、删除、更新和查询等操作
46
数据库存储
◦ 添加功能
◦ 首先构造一个ContentValues对象,然后调用
ContentValues对象的put()方法,将每个属性的
值写入到ContentValues对象中,最后使用
SQLiteDatabase对象的insert()函数,将
ContentValues对象中的数据写入指定的数据库
表中
◦ insert()函数的返回值是新数据插入的位置,即
ID值。ContentValues类是一个数据承载容器,
主要用来向数据库表中添加一条数据
47
数据库存储
◦ 删除功能
◦ 删除数据比较简单,只需要调用当前数据库对象的delete()函数,
并指明表名称和删除条件即可
1.
2.
3.
4.
5.
6.
public long deleteAllData() {
return db.delete(DB_TABLE, null, null);
}
public long deleteOneData(long id) {
return db.delete(DB_TABLE, KEY_ID + "=" + id, null);
}
◦
◦
◦
delete()函数的第1个参数是数据库的表名称,第2个参数是删除条件
在第2行代码中,删除条件为null,表示删除表中的所有数据
第6行代码指明了需要删除数据的id值,因此deleteOneData()函数仅删
除一条数据,此时delete()函数的返回值表示被删除的数据的数量
48
数据库存储
更新功能
◦ 更新数据同样要使用ContentValues对象,首先
构造ContentValues对象,然后调用put()函数将
属性的值写入到ContentValues对象中,最后使
用SQLiteDatabase对象的update()函数,并指定
数据的更新条件
49
数据库存储
查询功能
◦
◦
首先介绍Cursor类。在Android系统中,数据库查询结果
的返回值并不是数据集合的完整拷贝,而是返回数据集
的指针,这个指针就是Cursor类
Cursor类支持在查询的数据集合中多种方式移动,并能
够获取数据集合的属性名称和序号
50
数据库存储
Cursor类的方法和说明
函数
moveToFirst
moveToNext
moveToPrevious
getCount
getColumnIndexOrThrow
getColumnName
getColumnNames
getColumnIndex
moveToPosition
getPosition
说明
将指针移动到第一条数据上
将指针移动到下一条数据上
将指针移动到上一条数据上
获取集合的数据数量
返回指定属性名称的序号,如果属性不存在则
产生异常
返回指定序号的属性名称
返回属性名称的字符串数组
根据属性名称返回序号
将指针移动到指定的数据上
返回当前指针的位置
51
数据库存储
◦ 在提取Cursor数据中的数据前,推荐测试Cursor中的
数据数量,避免在数据获取中产生异常
◦ 从Cursor中提取数据使用类型安全的get<Type>()函数,
函数的输入值为属性的序号,为了获取属性的序号,
可以使用getColumnIndex()函数获取指定属性的序号
52
数据库存储
◦ 要进行数据查询就需要调用SQLiteDatabase类的
query()函数,query()函数的语法如下
Cursor android.database.sqlite.SQLiteDatabase.query(String table, String[] columns,
String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
◦ query()函数的参数说明
位置
1
2
3
4
类型+名称
String table
String[] columns
String selection
String[] selectionArgs
5
6
7
String groupBy
String having
String orderBy
说明
表名称
返回的属性列名称
查询条件
如果在查询条件中使用的问号,则需要
定义替换符的具体内容
分组方式
定义组的过滤器
排序方式
53
数据库存储-ToDoList5
使用数据库保存当前的待办事项
步骤1:创建一个ToDoDBAdapter类,用来管理数据库交互。
步骤2:修改主活动代码,增加数据库操作。
(参见工程ToDoList5)
内容提供器
默认情况下,数据库的访问权限仅限于创建它
的应用程序
内容提供器(Content Provider)提供了一个标
准的接口,可供应用程序在与其它应用程序
(包括许多本地数据存储)共享数据和使用这
些应用程序的数据时使用
通过分离数据存储层和应用程序层,内容提供
器为任意数据源提供了一个通用的接口
提供了一种基于使用content://模式的简单URI
地址模型来发布和使用数据的接口
55
内容提供器
通过扩展ContentProvider可以创建新的内容提供器
◦ 重写onCreate方法
◦ 提供URI的公共静态CONTENT_URI属性
◦ content://com.<company>.provider.<application>/<datapath> 对所有
值的请求
◦ content://com.<company>.provider.<application>/<datapath>/<rowNu
mber> 对一条记录的请求
◦ 通过创建和配置一个UriMatcher来解析URI以确定它们的形式
通过实现delete、insert、update和query方法来提供
对内容提供器的查询和事务操作
注册到应用程序清单中,authorities标签指定基本
URI
<provider android:name=“MyProvider”
android:authorities=“com.mycompany.provider.myapp”/>
56
内容提供器
public class MyProvider extends ContentProvider {
private static final String myURI = "content://com.mycompany.provider.myapp/items";
public static final Uri CONTENT_URI = Uri.parse(myURI);
@Override
public boolean onCreate() {
// TODO: Construct the underlying database.
return true;
}
// Create the constants used to differentiate between the different URI
// requests.
private static final int ALLROWS = 1;
private static final int SINGLE_ROW = 2;
private static final UriMatcher uriMatcher;
57
内容提供器
// Populate the UriMatcher object, where a URI ending in 'items' will
// correspond to a request for all items, and 'items/[rowID]'
// represents a single row.
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.example.provider.myApp", "items", ALLROWS);
uriMatcher.addURI("com.example.provider.myApp", "items/#", SINGLE_ROW);
}
}
58
内容解析器
每个应用程序的上下文都有一个内容解析器
(ContentResolver)实例,使用getContentResolver方
法来对其进行访问
包含多种修改和查询内容提供器的方法
可以使用一个URI来指定要交互的提供器,并将其传
递给这些方法
在内容提供器中访问文件
◦ 内容提供器使用完全限定的URI来表示文件,而不是使用原
始的文件大数据库
◦ 使用内容解析器的openOutputStream和openInputStream方法
可将一个文件插入到一个内容提供器中或访问一个已保存的
文件
59
内容提供器
Android.provider包提供一些类来方便访问android提供的内容提供器
http://developer.android.com/reference/android/provider/packagesummary.html
Q&A