使用内容提供者的主要目的是因为前面的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;
}
}