22读书笔记之创建自己的内容提供器
2017-08-29 17:41
218 查看
新建一个类继承ContentProvider的方式来创建一个自己的内容提供器。
ContentProvider类中有6个抽象方法,我们在使用子类继承它的时候,需要将这六个方法全部重写。
新建 MyProvider 继承自 ContentProvider。复写几个方法。
1. onCreate()
初始化内容提供器的时候调用,通常会在这里完成对数据库的创建和升级等操作.
返回 true 表示内容提供器初始化成功,返回 false 则表示失败。
注意,只有当存在 ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。
2. query()
从内容提供器中查询数据。
使用 uri 参数来确定查询哪张表,projection 参数用于确定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于对结果进行排序。
查询的结果存放在 Cursor 对象中返回。
4000
3. insert()
向内容提供器中添加一条数据。
使用 uri 参数来确定要添加到的表,待添加的数据保存在 values 参数中。
添加完成后,返回一个用于表示这条新记录的 URI。
4. update()
更新内容提供器中已有的数据。
使用 uri 参数来确定更新哪一张表中的数据,新数据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行。
受影响的行数将作为返回值返回。
5. delete()
从内容提供器中删除数据。
使用 uri 参数来确定删除哪一张表中的数据,selection 和 selectionArgs 参数用于约束删除哪些行。
被删除的行数将作为返回值返回。
6. getType()
根据传入的内容 URI 来返回相应的 MIME 类型。
一个内容 URI 所对应的 MIME 字符串主要由三部分组分:
必须以 vnd. 开头。
如果内容 URI 以路径结尾,则后接 android.cursor.dir/,如果内容 URI 以 id 结尾,则后接 android.cursor.item/。
最后接上 vnd..。
对于 content://com.example.app.provider/table1,对应的 MIME 类型为:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
对于 content://com.example.app.provider/table1/1,对应的 MIME 类型为:
vnd.android.cursor.item/vnd.com.example.app.provider.table1
实现 getType() 逻辑 :
借助 UriMatcher 匹配内容 URI,得知传入的 Uri 对象是想访问哪张表中的哪条数据。
能够匹配任意表的内容 URI:
content://com.example.app.provider/*
能够匹配 table1 表中任意一行数据的内容 URI:
content://com.example.app.provider/table1/#
UriMatcher 中提供了一个 addURI() 方法,接收三个参数,可以分别把权限、路径和一个自定义代码传进去。
当调用 UriMatcher 的 match() 方法时,就可以将一个 Uri 对象传入,返
回值是某个能够匹配这个 Uri 对象所对应的自定义代码。
利用这个代码,我们就可以判断出调用方期望访问的是哪张表或哪一行中的数据了。
在 MyProvider 的几个方法中用 switch 判断 uriMatcher.match(uri),根据不同 Uri 的目的,把目的定位到相应表或行。
明确目的后,具体靠对 SQLiteDatabase 进行操作完成增删改查。
getPathSegments() 方法
它会将内容 URI 权限之后的部分以 “/” 符号进行分割,并把分割后的结果放入到一个字符串列表中,这个列表的第 0 个位置存放的就是路径,第 1 个位置存放的就是 id。
要在 AndroidManifest.xml 里注册。
ContentProvider类中有6个抽象方法,我们在使用子类继承它的时候,需要将这六个方法全部重写。
新建 MyProvider 继承自 ContentProvider。复写几个方法。
public class MyProvider extends ContentProvider { @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public String getType(Uri uri) { return null; } }
1. onCreate()
初始化内容提供器的时候调用,通常会在这里完成对数据库的创建和升级等操作.
返回 true 表示内容提供器初始化成功,返回 false 则表示失败。
注意,只有当存在 ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。
2. query()
从内容提供器中查询数据。
使用 uri 参数来确定查询哪张表,projection 参数用于确定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于对结果进行排序。
查询的结果存放在 Cursor 对象中返回。
4000
3. insert()
向内容提供器中添加一条数据。
使用 uri 参数来确定要添加到的表,待添加的数据保存在 values 参数中。
添加完成后,返回一个用于表示这条新记录的 URI。
4. update()
更新内容提供器中已有的数据。
使用 uri 参数来确定更新哪一张表中的数据,新数据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行。
受影响的行数将作为返回值返回。
5. delete()
从内容提供器中删除数据。
使用 uri 参数来确定删除哪一张表中的数据,selection 和 selectionArgs 参数用于约束删除哪些行。
被删除的行数将作为返回值返回。
6. getType()
根据传入的内容 URI 来返回相应的 MIME 类型。
一个内容 URI 所对应的 MIME 字符串主要由三部分组分:
必须以 vnd. 开头。
如果内容 URI 以路径结尾,则后接 android.cursor.dir/,如果内容 URI 以 id 结尾,则后接 android.cursor.item/。
最后接上 vnd..。
对于 content://com.example.app.provider/table1,对应的 MIME 类型为:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
对于 content://com.example.app.provider/table1/1,对应的 MIME 类型为:
vnd.android.cursor.item/vnd.com.example.app.provider.table1
实现 getType() 逻辑 :
public class MyProvider extends ContentProvider { ...... @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case TABLE1_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1"; case TABLE1_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider.table1"; case TABLE2_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2"; case TABLE2_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider.table2"; default: break; } return null; } }
借助 UriMatcher 匹配内容 URI,得知传入的 Uri 对象是想访问哪张表中的哪条数据。
能够匹配任意表的内容 URI:
content://com.example.app.provider/*
能够匹配 table1 表中任意一行数据的内容 URI:
content://com.example.app.provider/table1/#
UriMatcher 中提供了一个 addURI() 方法,接收三个参数,可以分别把权限、路径和一个自定义代码传进去。
当调用 UriMatcher 的 match() 方法时,就可以将一个 Uri 对象传入,返
回值是某个能够匹配这个 Uri 对象所对应的自定义代码。
利用这个代码,我们就可以判断出调用方期望访问的是哪张表或哪一行中的数据了。
public static final int TABLE1_DIR = 0; public static final int TABLE1_ITEM = 1; public static final int TABLE2_DIR = 2; public static final int TABLE2_ITEM = 3; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR); uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM); }
在 MyProvider 的几个方法中用 switch 判断 uriMatcher.match(uri),根据不同 Uri 的目的,把目的定位到相应表或行。
public class MyProvider extends ContentProvider {
public static final int TABLE1_DIR = 0; public static final int TABLE1_ITEM = 1; public static final int TABLE2_DIR = 2; public static final int TABLE2_ITEM = 3; private static UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR); uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM); uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM); }
......
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch (uriMatcher.match(uri)) {
case TABLE1_DIR:
// 查询table1表中的所有数据
break;
case TABLE1_ITEM:
// 查询table1表中的单条数据
break;
case TABLE2_DIR:
// 查询table2表中的所有数据
break;
case TABLE2_ITEM:
// 查询table2表中的单条数据
break;
default:
break;
}
......
}
......
}
明确目的后,具体靠对 SQLiteDatabase 进行操作完成增删改查。
public class DatabaseProvider extends ContentProvider { public static final int BOOK_DIR = 0; public static final int BOOK_ITEM = 1; public static final int CATEGORY_DIR = 2; public static final int CATEGORY_ITEM = 3; public static final String AUTHORITY = "com.example.databasetest.provider"; private static UriMatcher uriMatcher; private MyDatabaseHelper dbHelper; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR); uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM); uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR); uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM); } @Override public boolean onCreate() {dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询数据 SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = null; switch (uriMatcher.match(uri)) { case BOOK_DIR: cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); cursor = db.query("Book", projection, "id = ?", new String[]{ bookId }, null, null, sortOrder); break; case CATEGORY_DIR: cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); cursor = db.query("Category", projection, "id = ?", new String[] { categoryId }, null, null, sortOrder); break; default: break; } return cursor; } @Override public Uri insert(Uri uri, ContentValues values) { // 添加数据 SQLiteDatabase db = dbHelper.getWritableDatabase(); Uri uriReturn = null; switch (uriMatcher.match(uri)) { case BOOK_DIR: case BOOK_ITEM: long newBookId = db.insert("Book", null, values); uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId); break; case CATEGORY_DIR: case CATEGORY_ITEM: long newCategoryId = db.insert("Category", null, values); uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId); break; default: break; } return uriReturn; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // 更新数据 SQLiteDatabase db = dbHelper.getWritableDatabase(); int updatedRows = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: updatedRows = db.update("Book", values, selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); updatedRows = db.update("Book", values, "id = ?", new String[] { bookId }); break; case CATEGORY_DIR: updatedRows = db.update("Category", values, selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId }); break; default: break; } return updatedRows; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // 删除数据 SQLiteDatabase db = dbHelper.getWritableDatabase(); int deletedRows = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: deletedRows = db.delete("Book", selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); deletedRows = db.delete("Book", "id = ?", new String[] { bookId }); break; case CATEGORY_DIR: deletedRows = db.delete("Category", selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); deletedRows = db.delete("Category", "id = ?", new String[] { categoryId }); break; default: break; } return deletedRows; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case BOOK_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.book"; case BOOK_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.book"; case CATEGORY_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.category"; case CATEGORY_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.category"; } return null; } }
getPathSegments() 方法
它会将内容 URI 权限之后的部分以 “/” 符号进行分割,并把分割后的结果放入到一个字符串列表中,这个列表的第 0 个位置存放的就是路径,第 1 个位置存放的就是 id。
要在 AndroidManifest.xml 里注册。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.databasetest" android:versionCode="1" android:versionName="1.0" > ...... <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > ...... <provider android:name="com.example.databasetest.DatabaseProvider" android:authorities="com.example.databasetest.provider" > </provider> </application> </manifest>
相关文章推荐
- android: 创建自己的内容提供器
- Andriod---创建自己的内容提供器
- Android初级开发(七)——创建自己的内容提供器
- Android开发之创建自己的内容提供器并测试
- android 学习笔记 创建自己的内容提供器
- 【练习】内容提供器二、创建自己的内容提供器并测试
- 第一行代码-7.3 创建自己的内容提供器
- 创建自己的内容提供器
- Android之 内容提供器(2)——创建自己的内容提供器将数据共享出去
- Android编程之创建自己的内容提供器实现方法
- Android 创建内容提供器(ContentResolver)
- Android 内容提供器---创建内容提供器(实现合约类)
- ContentProvider 学习(2)创建内容提供程序
- Android内容提供者(二)创建自己的Provider
- Android 内容提供器---创建内容提供器(实现内容提供器权限)
- Creating a Content Provider 创建一个内容提供器
- Android 内容提供器---创建内容提供器(实现ContentProvider类)
- Android 内容提供器---创建内容提供器(<provider>元素)
- 内容提供者 Content Provider - 创建
- webservice的创建、发布及调用示例(以调用自己发布的webservice和中国气象局提供的webservice为例)