内容提供器

一、基本用法

内容提供器使数据在不同的程序中实现共享

主要分为两种,一种是现有的内容提供器,第二是自己程序的内容提供器

ContentResolver

如果要访问共享数据,必须要借助getContentResolver得到实例进行CRUD操作

接受的地址是Uri参数,用Uri uri.parse解析成URI再传递进去

Uri uri = uri.parse("content://com.example.app.provider/table1");

查询

Cursor cursor = getContentResolver().quety(uri, projection, selection, selectionArgs, orderBy);

if (cursor != null){
	while (cursor.moveToNext()){
	String column1 = cursor.getString(cursor.getColumIndex("column1"));
	int column2 = cursor.getInt(cursor.getColumIndex("column2"));
	}
}

添加

ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver.insert(uri, values);

更新

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver.update(uri, values, "column1 = ?", new String[] {"text" , "1"});

删除

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver.delete(uri, values, "column2 = ?", new String[] {"1"});


二、使用现有的内容提供器—读取联系人

MainActivity:

在onCreate方法中,创建一个ListView,一个适配器,将读出的联系人写入到适配器的数据中

public class MainActivity extends ActionBarActivity {
	
	ListView contactsView;
	
	ArrayAdapter<String> adapter;
	
	List<String> contactsList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contactsView = (ListView) findViewById(R.id.contacts_view);
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
        contactsView.setAdapter(adapter);
        readContacts();//读取联系人
    }

readContacts:

查找效应的联系人,放到ArrayList中去
传入的是系统设置好的对应的URI
 private void readContacts(){
    	Cursor cursor = null;
    	try{
    		//查询联系人数据
    		cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    		while (cursor.moveToNext()) {
    			//获取联系人姓名
    			String displayName = cursor.getString(cursor.getColumnIndex(
    					ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
    			//获取联系人手机
    			String number = cursor.getString(cursor.getColumnIndex(
    					ContactsContract.CommonDataKinds.Phone.NUMBER));
    			contactsList.add(displayName + "\n" + number); 
    		}
    	}catch (Exception e){
    		e.printStackTrace();
    	}finally{
    		if (cursor != null){
    			cursor.close();
    		}
    	}
    }

三、创建自己的内容管理器

1.继承ContentProvider

首先要用uriMatcher.addURI方法把希望匹配的表中的信息写进去,用来后面判断访问的是哪张表
分别代表访问表中的全部数据和单条数据
public class MyProvider extends ContentProvider{
	
	public static final int TABLE1_DIR = 0;
	
	public static final int TABLE1_ITEM = 1;
	
	public static final int TABLE2_DIR = 2;
	
	public static final int TABLE2_ITEM = 3;
	
	private static UriMatcher uriMatcher;
	
	static{
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
		uriMatcher.addURI("com.example.app.provider", "table1/#", TABLE1_ITEM);
		uriMatcher.addURI("com.example.app.provider", "table2", TABLE2_ITEM);
		uriMatcher.addURI("com.example.app.provider", "table2/#", TABLE2_ITEM);
	}

2.重写里面的五个方法

1.onCreate()

返回true表示创建内容提供器成功
@Override
	public boolean onCreate() {
		dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
		return true;
	}

2.query()

创建数据库的实例,用match方法判断访问的是哪张表
注意在查询单条数据的时候,用uri.getPathSegments().get(1)方法取得要查找的ID,在后面的selection函数中来限制查询的条件
最后要返回一个cursor类型
@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 查询数据
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor cursor = null;
		switch (uriMatcher.match(uri)){
		
		case BOOK_DIR:
			cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
			break;
			
		case BOOK_ITEM:
			String bookId = uri.getPathSegments().get(1);
			cursor = db.query("Book", projection, "id = ?", new String[]{bookId}, null, null, sortOrder);
			break;
			
		case CATEGORY_DIR:
			cursor = db.query("Category", projection,  selection, selectionArgs, null, null, sortOrder);
			break;
			
		case CATEGORY_ITEM:
			String categoryId = uri.getPathSegments().get(1);
			cursor = db.query("Category", projection, "id = ?", new String[]{categoryId}, null, null, sortOrder);
			break;
			default:
				break;
		}
		return cursor;
	}

3.getTyoe()

是为了得到URI的MINE类型
注意与路径结尾和与ID结尾的不同

@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		
		case BOOK_DIR:			
			return "vnd.android.cursor.dir/vnd.con,example.databasetest.provider.book";
			
		case BOOK_ITEM:
			return "vnd.android.cursor.item/vnd.con,example.databasetest.provider.book";
		
		case CATEGORY_DIR:
			return "vnd.android.cursor.dir/vnd.con,example.databasetest.provider.category";
			
		case CATEGORY_ITEM:
			return "vnd.android.cursor.item/vnd.con,example.databasetest.provider.category";
		}
		return null;
	}

4.insert()

返回值是插入数据的URI,用一个newBookID记录插入的返回值,再解析成为URI传回来
public Uri insert(Uri uri, ContentValues values) {
		// 添加数据
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		Uri uriReturn = null;
		switch (uriMatcher.match(uri)) {
		case BOOK_DIR:
		case BOOK_ITEM:
			long newBookId = db.insert("Book", null, values);
			uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
			break;
		case CATEGORY_DIR:
		case CATEGORY_ITEM:
			long newCategoryId = db.insert("Category", null, values);
			uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);
			break;
			default:
				break;
		}
		return uriReturn;
	}

5.delete()

返回值是删除的行数

@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// 删除数据
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int deleteRows = 0;
		switch (uriMatcher.match(uri)){
		
		case BOOK_DIR:
			deleteRows = db.delete("Book", selection, selectionArgs);
			break;
			
		case BOOK_ITEM:
			String bookId = uri.getPathSegments().get(1);
			deleteRows = db.delete("Book", "id = ?", new String[]{ bookId });
			break;
			
		case CATEGORY_DIR:
			deleteRows = db.delete("Category", selection, selectionArgs);
			break;
			
		case CATEGORY_ITEM:
			String categoryId = uri.getPathSegments().get(1);
			deleteRows = db.delete("Category", "id = ?", new String[]{ categoryId });
			break;	
			
		default:
			break;
		}
		return deleteRows;
	}

5.update

@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// 更新数据
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int updatedRows = 0;
		switch (uriMatcher.match(uri)){
		case BOOK_DIR:
			updatedRows = db.update("Book", values, selection, selectionArgs);
			break;
		case BOOK_ITEM:
			String bookId = uri.getPathSegments().get(1);
			updatedRows = db.update("Book", values, "id = ?", new String[]{ bookId });
			break;
		case CATEGORY_DIR:
			updatedRows = db.update("Category", values, selection, selectionArgs);
			break;
		case CATEGORY_ITEM:
			String categoryId = uri.getPathSegments().get(1);
			updatedRows = db.update("Category", values, "id = ?", new String[]{ categoryId });
			break;	
			default:
			break;
		}
		return updatedRows;
	}


四、从外部访问

Uri uri = uri.parse("content://com.example.app.provider/book");
COntentValues values = new COntentValues();
values.put("name", "A clash of Kings");
values.put("author", "George Martin");
values.put("pages", 1040);
Uri newUri = getContentResolver().insert(uri, values);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值