使用内容提供者的主要目的是因为前面的SQLite创建存储的数据仅仅能在App内部使用,这样固然提高了安全性,但有时候我们需要使用其他app的数据。
内容提供者提供数据,内容解析者读取或者修改数据,当然需要相应的权限。
第一步,我们必须像之前那样去实现一个SQLiteOpenHelper的子类,以便于我们能够去使用SQLite
第二步,创建一个对象,来继承ContentProvider,主要的工作在这里进行。
这时,在清单文件中注册这个提供者,并提供一些授权,提供数据访问路径,因为这里的工作就是为了给外部App去访问数据
然后在刚才的class中增加一些匹配规则:
// 添加两条匹配规则 static { URI_MATCHER.addURI( "com.example.android_content_provider.StudentProvider", "student", STUDENTS); URI_MATCHER.addURI( "com.example.android_content_provider.StudentProvider", "student/#", STUDENT); }
因此,在下面的每个方法的实现中都要通过匹配URI,来判断要操作的是某一项还是多项。
例如:
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor = null; SQLiteDatabase database = null; try { database = helper.getReadableDatabase(); int flag = URI_MATCHER.match(uri); switch (flag) { case STUDENT: long id = ContentUris.parseId(uri); String where_value = " id = " + id; if (selection != null && !selection.equals("")) { where_value += " and " + selection; } cursor = database.query("student", null, where_value, selectionArgs, null, null, null, null); break; case STUDENTS: cursor = database.query("student", null, selection, selectionArgs, null, null, null); break; } } catch (Exception e) { // TODO: handle exception } return cursor; }
如何去使用内容提供者? 我们在单元测试中这样写:
public void testQuery(){ ContentResolver contentResolver = getContext().getContentResolver(); //查询单条记录 content://com.example.android_content_provider.StudentProvider/student/2 //查询多条记录 content://com.example.android_content_provider.StudentProvider/student Uri uri = Uri .parse("content://com.example.android_content_provider.StudentProvider/student"); //select * from student where id = 2 Cursor cursor = contentResolver.query(uri, null, null, null, null); while(cursor.moveToNext()){ Log.i("MyTest", "--->" + cursor.getString(cursor.getColumnIndex("name"))); } }
完整的StudentContentProvider实现如下:
package com.example.android_content_provider; 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; import android.util.Log; public class StudentProvider extends ContentProvider { private final String TAG = "StudentProvider"; private DBHelper helper = null; private static final UriMatcher URI_MATCHER = new UriMatcher( UriMatcher.NO_MATCH); private static final int STUDENT = 1; // 表示操作单条记录 private static final int STUDENTS = 2; // 操作多条记录 // 添加两条匹配规则 static { URI_MATCHER.addURI( "com.example.android_content_provider.StudentProvider", "student", STUDENTS); URI_MATCHER.addURI( "com.example.android_content_provider.StudentProvider", "student/#", STUDENT); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count = -1; // 影响数据库的行数 try { int flag = URI_MATCHER.match(uri); SQLiteDatabase database = helper.getWritableDatabase(); switch (flag) { case STUDENT: // delete from student where id = ? //id通过客户端传递过来 long id = ContentUris.parseId(uri); String where_value = " id = " + id; if (selection != null && !selection.equals("")) { where_value += " and " + selection; } count = database.delete("student", where_value, selectionArgs); Log.i(TAG, "delete-->" + count); break; case STUDENTS: count = database.delete("student", selection, selectionArgs); break; } } catch (Exception e) { // TODO: handle exception } return count; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub int flag = URI_MATCHER.match(uri); switch (flag) { case STUDENT: return "vnd.android.cursor.item/student"; case STUDENTS: return "vnd.android.cursor.dir/students"; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { // insert into student () (?,?); Uri resultUri = null; int flag = URI_MATCHER.match(uri); // 插入操作对应的是复数 // 查询 删除 更改对应的才是单数 switch (flag) { case STUDENTS: SQLiteDatabase database = helper.getWritableDatabase(); long id = database.insert("student", null, values); // 插入当前行的行号 Log.i(TAG, "---->> " + uri); Log.i(TAG, "---->> " + id); // 扩展之后变为插入的那条记录的URI resultUri = ContentUris.withAppendedId(uri, id); break; } Log.i(TAG, "---->>" + resultUri.toString()); return resultUri; } @Override public boolean onCreate() { // TODO Auto-generated method stub helper = new DBHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor = null; SQLiteDatabase database = null; try { database = helper.getReadableDatabase(); int flag = URI_MATCHER.match(uri); switch (flag) { case STUDENT: long id = ContentUris.parseId(uri); String where_value = " id = " + id; if (selection != null && !selection.equals("")) { where_value += " and " + selection; } cursor = database.query("student", null, where_value, selectionArgs, null, null, null, null); break; case STUDENTS: cursor = database.query("student", null, selection, selectionArgs, null, null, null); break; } } catch (Exception e) { // TODO: handle exception } return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count = -1; try { SQLiteDatabase database = helper.getWritableDatabase(); // update table set name = ? ,address =? where id = ? long id = ContentUris.parseId(uri); int flag = URI_MATCHER.match(uri); switch (flag) { case STUDENT: String where_value = " id = " + id; if (selection != null && !selection.equals("")) { where_value += " and " + selection; } count = database.update("student", values, where_value, selectionArgs); break; } } catch (Exception e) { // TODO: handle exception } return count; } }