ContentProvider的增删改查和优化
事先说明:
ContentProvider步骤:创数据库,写规则匹配,配置manifests,另一个应用使用
其实ContentProvider就是:在一个匹配器中写入自己写好的匹配规则,并对外提供写好的匹配规则供使用,剩下的就是增删改查的处理
细节处理:
在增删改查中的查询中,是没有cursor.getBoolean这个方法的,所以要对数据库中获取布尔值进行处理:
msg.setFlag(cursor.getInt(cursor.getColumnIndex("flag")) != 0);
ContentProvider的增删改查
步骤一:创建一个类继承SQLiteOpenHelper,并用SQL语句创建一个SQLite
public class CommonOpenHelper extends SQLiteOpenHelper { private static CommonOpenHelper helper; public static CommonOpenHelper getInstance(Context context) { if (helper == null) { helper = new CommonOpenHelper(context, "common.db", null, 1); } return helper; } private CommonOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table message(" + "id integer primary key autoincrement, " + "content varchar, " + "date varchar " + ")"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
public class MyMessageProvider extends ContentProvider { //数据库名 public final static String DB_MESSAGE = "message"; //放置一个数据库 CommonOpenHelper helper; SQLiteDatabase db; //空白匹配器 UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //自身的匹配规则 final static int CODE_MESSAGE_INSERT = 0; final static int CODE_MESSAGE_QUERY = 1; final static int CODE_MESSAGE_DELETE = 2; final static int CODE_MESSAGE_UPDATE = 3; //主机名 final static String authority = "com.handsome.nfcc"; final static Uri BASE_URI = Uri.parse("content://com.handsome.nfcc"); //写入该主机名的匹配规则 { matcher.addURI(authority, "message/insert", CODE_MESSAGE_INSERT); matcher.addURI(authority, "message/query", CODE_MESSAGE_QUERY); matcher.addURI(authority, "message/delete", CODE_MESSAGE_DELETE); matcher.addURI(authority, "message/update", CODE_MESSAGE_UPDATE); } //对外提供的URI public interface URI { Uri CODE_MESSAGE_INSERT = Uri.parse("content://" + authority + "/message/insert"); Uri CODE_MESSAGE_QUERY = Uri.parse("content://" + authority + "/message/query"); Uri CODE_MESSAGE_DELETE = Uri.parse("content://" + authority + "/message/delete"); Uri CODE_MESSAGE_UPDATE = Uri.parse("content://" + authority + "/message/update"); } @Override public boolean onCreate() { helper = CommonOpenHelper.getInstance(getContext()); db = helper.getWritableDatabase(); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch (matcher.match(uri)) { case CODE_MESSAGE_QUERY: Cursor cursor = db.query(DB_MESSAGE, projection, selection, selectionArgs, null, null, sortOrder); //注册内容观察者,观察数据变化 cursor.setNotificationUri(getContext().getContentResolver(), BASE_URI); return cursor; default: throw new IllegalArgumentException("未识别的uri" + uri); } } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { switch (matcher.match(uri)) { case CODE_MESSAGE_INSERT: long rowId = db.insert(DB_MESSAGE, null, values); if (rowId == -1) { //添加失败 return null; } else { //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); //添加成功 return ContentUris.withAppendedId(uri, rowId); } default: throw new IllegalArgumentException("未识别的uri" + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { switch (matcher.match(uri)) { case CODE_MESSAGE_DELETE: int number = db.delete(DB_MESSAGE, selection, selectionArgs); //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); return number; default: throw new IllegalArgumentException("未识别的uri" + uri); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { switch (matcher.match(uri)) { case CODE_MESSAGE_UPDATE: int number = db.update(DB_MESSAGE, values, selection, selectionArgs); //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); return number; default: throw new IllegalArgumentException("未识别的uri" + uri); } } }
<provider android:name=".Provider.MyMessageProvider" android:authorities="com.handsome.nfcc" />
public class MessageDao { /** * 添加数据 */ public static boolean insert(ContentResolver resolver, Message msg) { ContentValues values = new ContentValues(); values.put("content", msg.getContent()); values.put("date", DateUtils.showDate()); resolver.insert(MyMessageProvider.URI.CODE_MESSAGE_INSERT, values); return true; } /** * 删除数据 */ public static void delete(ContentResolver resolver, int id) { resolver.delete(MyMessageProvider.URI.CODE_MESSAGE_DELETE, "id = " + id, null); } /** * 删除全部数据 */ public static void deleteAll(ContentResolver resolver) { resolver.delete(MyMessageProvider.URI.CODE_MESSAGE_DELETE, null, null); } /** * 查询数据 * * @param resolver * @return */ public static List<Message> query(ContentResolver resolver) { List<Message> list = new ArrayList<>(); Cursor cursor = resolver.query(MyMessageProvider.URI.CODE_MESSAGE_QUERY, null, null, null, null); while (cursor.moveToNext()) { Message msg = new Message(); msg.setDate(cursor.getString(cursor.getColumnIndex("date"))); msg.setContent(cursor.getString(cursor.getColumnIndex("content"))); msg.setId(cursor.getInt(cursor.getColumnIndex("id"))); list.add(0, msg); } return list; } }
ContentProvider的优化
往往在一个项目中有很多的数据库,这个时候并不是重复的写ContentProvider代码,而是将所有数据库中放在一个ContentProvider中,提供一个查询表名的方法,并对其相应的表进行操作
步骤一:ContentProvider的代码优化(一套代码适用多个数据库)
public class MyDataProvider extends ContentProvider { //数据库名 public final static String DB_DATA = "data"; public final static String DB_FETCH = "fetch"; public final static String DB_MESSAGE = "message"; //放置一个数据库 CommonOpenHelper helper; SQLiteDatabase db; UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //自身的匹配规则 final static int CODE_DATA = 0; final static int CODE_FETCH = 1; final static int CODE_MESSAGE = 2; //主机名 final static String authority = "com.handsome.nfc"; final static Uri BASE_URI = Uri.parse("content://com.handsome.nfc"); //写入该主机名的匹配规则 { matcher.addURI(authority, "data", CODE_DATA); matcher.addURI(authority, "fetch", CODE_FETCH); matcher.addURI(authority, "message", CODE_MESSAGE); } //对外提供的URI public interface URI { Uri DATA_CONTENT_URI = Uri.parse(BASE_URI + "/data"); Uri FETCH_CONTENT_URI = Uri.parse(BASE_URI + "/fetch"); Uri MESSAGE_CONTENT_URI = Uri.parse(BASE_URI + "/message"); } /** * 获取数据库表名 * * @param uri * @return */ private String getTableName(Uri uri) { String tableName = null; switch (matcher.match(uri)) { case CODE_DATA: tableName = DB_DATA; break; case CODE_FETCH: tableName = DB_FETCH; break; case CODE_MESSAGE: tableName = DB_MESSAGE; break; default: break; } return tableName; } @Override public boolean onCreate() { helper = CommonOpenHelper.getInstance(getContext()); db = helper.getWritableDatabase(); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { String tableName = getTableName(uri); if (tableName == null) { throw new IllegalArgumentException("非法Uri:" + uri); } Cursor cursor = db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder); //注册内容观察者,观察数据变化 cursor.setNotificationUri(getContext().getContentResolver(), BASE_URI); return cursor; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { String tableName = getTableName(uri); if (tableName == null) { throw new IllegalArgumentException("非法Uri:" + uri); } long rowId = db.insert(tableName, null, values); if (rowId == -1) { return null; } else { //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); return ContentUris.withAppendedId(uri, rowId); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { String tableName = getTableName(uri); if (tableName == null) { throw new IllegalArgumentException("非法Uri:" + uri); } int number = db.delete(tableName, selection, selectionArgs); //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); return number; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { String tableName = getTableName(uri); if (tableName == null) { throw new IllegalArgumentException("非法Uri:" + uri); } int number = db.update(tableName, values, selection, selectionArgs); //发送内容广播 getContext().getContentResolver().notifyChange(BASE_URI, null); return number; } }
步骤二:在各个不同的数据库中的使用
Data数据库通过名字查询示例
private static boolean queryDataByName(ContentResolver resolver, String tag_id) { Cursor cursor = resolver.query(MyDataProvider.URI.DATA_CONTENT_URI, null, "tag_id = '" + tag_id + "'", null, null); if (cursor.moveToFirst()) { return true; } return false; }Fetch数据库插入示例
public static boolean insert(ContentResolver resolver, Fetch fetch) { ContentValues values = new ContentValues(); values.put("fetch_num", fetch.getFetch_num()); values.put("username", fetch.getUsername()); values.put("installationId", fetch.getInstallationId()); values.put("created", fetch.getCreated()); values.put("date", System.currentTimeMillis()); resolver.insert(MyDataProvider.URI.FETCH_CONTENT_URI, values); return true; }Message数据库查询示例
public static List<Message> query(ContentResolver resolver) { List<Message> list = new ArrayList<>(); Cursor cursor = resolver.query(MyDataProvider.URI.MESSAGE_CONTENT_URI, null, null, null, null); while (cursor.moveToNext()) { Message msg = new Message(); msg.setDate(cursor.getString(cursor.getColumnIndex("date"))); msg.setContent(cursor.getString(cursor.getColumnIndex("content"))); msg.setId(cursor.getInt(cursor.getColumnIndex("id"))); list.add(0, msg); } return list; }