Android数据存储之ContentProvider

    上一篇博客讲了怎样去生成自己的数据库,以及对数据库的一些基本操作。在Android系统中,我们发现很多数据都是通过一个URi查询的,如联系人、短信等。要使你的数据支持通过Uri查询就需要实现自己的ContentProvider。

    是否需要构建自己的ContentProvider

    在你创建自己的ContentProvider之前,你得搞清楚自己的需求是否真的需要实现一个ContentProvider,满足以下一个或者多个需求的时候,你才需要创建自己的ContentProvider,否则不需要:

    1、你的应用程序需要给其他应用提供复杂数据,如联系人,除了本身使用联系人数据外,还要把这些数据共享短信等应用;

    2、你想给搜索框架提供自定义的搜索建议。

    设计你的查询Uri

    一个查询URI是由"scheme"、"authority"、"path"组成,还有一个可选择的"id"部分,带有id的URI对应了表格中的某一行。"scheme"一般指定为"content";为了各个Provider之间不产生冲突,"authority"推荐使用应用程序的包名,例如例子中使用的是"com.ns.note";"path"设置成表格名称即可。在构建URI的过程中,我们可以借助"Uri.Builder()"工具类,如:

Uri CONTENT_URI = new Uri.Builder().scheme(SCHEME).authority(AUTHORITY).path(TABLE_NAME).build();

    处理Content URI中的ID

    使用URI进行数据查询时,我们可以在URI中接一个ID,用来查询表格中"_id"字段等于ID的对应行的数据,我们可以通过下面代码所示的方式,解析出URI里面的ID:

long id = ContentUris.parseId(uri);

    匹配Content URI

    为了帮助我们搞清楚传递进来的URI要做的事情,Provider API为我们提供了UriMather类,该类能够根据事先约定好的规则,把URI匹配到一个整数,然后你可以根据这个整数来做对应的操作并返回对应的数据。

    可以使用以下通配符来匹配URI:

    *:匹配任意长度的有效字符;

    #:匹配任一长度的整数字符("12");

private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);	
static {
		mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME, NOTE);
		mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME + "/#", NOTE_ID);
	}

    下面是一个完整的ContentProvider的例子:

    

package com.ns.sqlite;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;

public class NotesProvider extends ContentProvider {
	
	private MaikuDBHelper mDbHelper = null;
	private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	
	private static final int NOTE = 1;
	private static final int NOTE_ID = 2;
	
	static {
		mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME, NOTE);
		mUriMatcher.addURI(NotesContract.AUTHORITY, NotesContract.Notes.TABLE_NAME + "/#", NOTE_ID);
	}

	@Override
	public boolean onCreate() {
		mDbHelper = new MaikuDBHelper(getContext());
		return true;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int result = -1;
		int match = mUriMatcher.match(uri);
		switch (match) {
		case 1:
			result =  mDbHelper.getWritableDatabase().delete(NotesContract.Notes.TABLE_NAME, selection, selectionArgs);
			break;
			
		case 2:
			long id = ContentUris.parseId(uri);
			String where = NotesContract.Notes._ID + " = " + id;
			if (selection != null && selection.trim().length()> 0) {
				where = selection + " and " + where;
			}
			result = mDbHelper.getWritableDatabase().delete(NotesContract.Notes.TABLE_NAME, where, selectionArgs);
			break;
			
		default:
			throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
		}
		
		//通知观察者数据发生变化
		getContext().getContentResolver().notifyChange(uri, null);
		return result;
	}

	@Override
	public String getType(Uri arg0) {
		int match = mUriMatcher.match(arg0);
		switch (match) {
		case 1:
			return "vnd.android.cursor.dir/note";
			
		case 2:
			return "vnd.android.cursor.item/person";

		default:
			throw new IllegalArgumentException("Unkwon Uri:" + arg0.toString());
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues arg1) {
		long id = mDbHelper.getWritableDatabase().insert(NotesContract.Notes.TABLE_NAME, null, arg1);
		//通知观察者数据发生变化
		getContext().getContentResolver().notifyChange(uri, null);
		return ContentUris.withAppendedId(NotesContract.Notes.CONTENT_URI, id);
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		Cursor cursor = null;
		int match = mUriMatcher.match(uri);
		switch (match) {
		case 1:
			cursor = mDbHelper.getReadableDatabase().query(NotesContract.Notes.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
			break;
			
		case 2:
			long id = ContentUris.parseId(uri);
			String where = NotesContract.Notes._ID + " = " + id;
			if (selection != null && selection.trim().length() > 0) {
				where = selection + " and "+ where;
			}
			cursor = mDbHelper.getReadableDatabase().query(NotesContract.Notes.TABLE_NAME, projection, where, selectionArgs, null, null, sortOrder);
			break;
			
		default:
			throw new IllegalArgumentException("unknow uri" + uri.toString());
		}
		
		if (cursor != null) {
			cursor.setNotificationUri(getContext().getContentResolver(), uri);
		}
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		int result = -1;
		int match = mUriMatcher.match(uri);
		switch (match) {
		case 1:
			result = mDbHelper.getWritableDatabase().update(NotesContract.Notes.TABLE_NAME, values, selection, selectionArgs);
			break;
			
		case 2:
			long id = ContentUris.parseId(uri);
			String where = NotesContract.Notes._ID + " = " + id;
			if (selection != null && selection.trim().length() > 0) {
				where = selection + " and " + where;
			}
			result = mDbHelper.getWritableDatabase().update(NotesContract.Notes.TABLE_NAME, values, where, selectionArgs);
			break;
			
		default:
			throw new IllegalArgumentException("unknow uri" + uri.toString());
		}
		
		//通知观察者数据发生变化
		getContext().getContentResolver().notifyChange(uri, null);
		return result;
	}

}
待续.....

说明:由于是第一次比较正经的写博客,可能内容组织不是太好,我会慢慢修改,知道自己满意为止。

转载于:https://my.oschina.net/fanxiao/blog/140581

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值