22读书笔记之创建自己的内容提供器
来源:互联网 发布:淘宝网tfboys同款书包 编辑:程序博客网 时间:2024/05/22 12:47
新建一个类继承ContentProvider的方式来创建一个自己的内容提供器。
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 对象中返回。
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>
- 22读书笔记之创建自己的内容提供器
- 创建自己的内容提供器ContentProvider
- 创建自己的内容提供器
- Andriod---创建自己的内容提供器
- Android开发之创建自己的内容提供器并测试
- android 学习笔记 创建自己的内容提供器
- 第一行代码-7.3 创建自己的内容提供器
- 20读书笔记之内容提供器
- Android初级开发(七)——创建自己的内容提供器
- 《第一行代码--Android》读书笔记之内容提供器
- Android创建内容提供器
- 操作数据库是否需要实现自己的内容提供器
- Android 内容提供器---创建内容提供器(实现ContentProvider的MIME类型)
- Android 内容提供器---创建内容提供器(实现ContentProvider的MIME类型)
- Android 之创建内容提供程序
- Android 内容提供器---创建内容提供器(概要)
- Android 内容提供器---创建内容提供器(概要)
- 内容提供器--2、创建内容提供器
- 微信135富文本编辑器编辑的样式与页面无法兼容的问题
- 阿里测评题目:跑得快
- MySQL事务回滚rollback与提交commit的操作
- HDU 5475 线段树 + 乘法+取模
- 测试
- 22读书笔记之创建自己的内容提供器
- 最短子数组
- MatLab GUI 学习笔记-数据传递
- jQuery插件mmGrid的使用
- ffmpeg开发之旅(4):MP3编码格式分析与lame库编译封装
- zookeeper启动时报错排除
- 在nginx中配置如何防止直接用ip访问服务器web server及server_name特性讲解
- php 简单实现无限递归分类
- 几种常用接口调用方式