【Android】ContentProvider的使用



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

STUDENT对应的是单数,也就是数据库中的某一行,STUDENTS则对应多行。


因此,在下面的每个方法的实现中都要通过匹配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;
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值