在前几篇里面,学的是使用ContentResolver来操作系统ContentProvider提供的数据,下面要学学开发自己的ContentProvider
开发自己的ContentProvider有两步
1.开发一个ContentProvider的子类,该子类需要实现增,删,改,查
2.在AndroidManifest.xml文件中注册该ContentProvider
实现增,删,改,查都需要有一个Uri参数,该参数决定对哪个Uri执行数据操作
Andriod提供了一个系统工具类UriMatcher
UriMatcher有两个重要方法
void addURI(String authority, String path, int Code) 用于向UriMatcher 对象注册Uri. 其中authority和path合成一个Uri,而code代表该Uri对应的标识码
int match(Uri uri) 根据前面注册的Uri来判断指定Uri对应的标识码.如果找不到匹配的标识码,该方法将会返回 -1.
UriMatcher类的使用
http://blog.sina.com.cn/s/blog_68586b420100jlqf.html
下面是把"初学Android,数据存储之使用SQLite数据库(四十六)"中的例子,生词本加入ContentProvider,这样允许其它程序通过ContentResolver来操作生词本
系统一般会把ContentProvider的Uri,数据列等信息以常量的形式公开出来,方便访问.因为,应该为ContentProvider定义一个工具类
访类中只是包含一个public static常量.
Words.java
package WangLi.IO.DictProvider; import android.net.Uri; import android.provider.BaseColumns; public final class Words { // 定义该ContentProvider的Authority public static final String AUTHORITY = "WangLi.providers.dictprovider"; //定义一个静态内部类 public static final class Word implements BaseColumns { // 定义Content所允许操作的3个数据列 public final static String _ID = "_id"; public final static String WORD = "word"; public final static String DETAIL = "detail"; // 定义该Content提供服务的两个Uri public final static Uri DICT_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/words"); public final static Uri WORD_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/word"); } }
package WangLi.IO.DictProvider; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class DictProvider extends ContentProvider { private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int WORDS = 1; private static final int WORD = 2; private MyDatabaseHelper dbOpenHelper; static { // 为UriMatcher注册两个Uri matcher.addURI(Words.AUTHORITY, "words", WORDS); matcher.addURI(Words.AUTHORITY, "word/#", WORD); } // 第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法 @Override public boolean onCreate() { dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1); return true; } // 插入数据方法 @Override public Uri insert(Uri uri, ContentValues values) { // 获得数据库实例 SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); // 插入数据,返回行ID long rowId = db.insert("dict", Words.Word._ID, values); // 如果插入成功返回uri if (rowId > 0) { // 在已有的 Uri的后面追加ID数据 Uri wordUri = ContentUris.withAppendedId(uri, rowId); // 通知数据已经改变 getContext().getContentResolver().notifyChange(wordUri, null); return wordUri; } return null; } // 删除数据的方法 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); // 记录所删除的记录数 int num = 0; // 对于uri进行匹配。 switch (matcher.match(uri)) { case WORDS: num = db.delete("dict", selection, selectionArgs); break; case WORD: // 解析出所需要删除的记录ID long id = ContentUris.parseId(uri); String where = Words.Word._ID + "=" + id; // 如果原来的where子句存在,拼接where子句 if (selection != null && !selection.equals("")) { where = where + " and " + selection; } num = db.delete("dict", where, selectionArgs); break; default: throw new IllegalArgumentException("未知Uri:" + uri); } // 通知数据已经改变 getContext().getContentResolver().notifyChange(uri, null); return num; } // 修改数据的方法 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); // 记录所修改的记录数 int num = 0; switch (matcher.match(uri)) { case WORDS: num = db.update("dict", values, selection, selectionArgs); break; case WORD: // 解析出想修改的记录ID long id = ContentUris.parseId(uri); String where = Words.Word._ID + "=" + id; // 如果原来的where子句存在,拼接where子句 if (selection != null && !selection.equals("")) { where = where + " and " + selection; } num = db.update("dict", values, where, selectionArgs); break; default: throw new IllegalArgumentException("未知Uri:" + uri); } // 通知数据已经改变 getContext().getContentResolver().notifyChange(uri, null); return num; } // 查询数据的方法 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); switch (matcher.match(uri)) { case WORDS: // 执行查询 return db.query("dict", projection, selection, selectionArgs, null, null, sortOrder); case WORD: // 解析出想查询的记录ID long id = ContentUris.parseId(uri); String where = Words.Word._ID + "=" + id; // 如果原来的where子句存在,拼接where子句 if (selection != null && !"".equals(selection)) { where = where + " and " + selection; } return db.query("dict", projection, where, selectionArgs, null, null, sortOrder); default: throw new IllegalArgumentException("未知Uri:" + uri); } } // 返回指定uri参数对应的数据的MIME类型 @Override public String getType(Uri uri) { switch (matcher.match(uri)) { // 如果操作的数据是多项记录 case WORDS: return "vnd.android.cursor.dir/org.crazyit.dict"; // 如果操作的数据是单项记录 case WORD: return "vnd.android.cursor.item/org.crazyit.dict"; default: throw new IllegalArgumentException("未知Uri:" + uri); } } }
注意在AndroidManifest.xml中加入刚刚的DictProvider
<!-- 注册一个ContentProvider --> <provider android:name=".DictProvider" android:authorities="org.crazyit.providers.dictprovider" />