ContentProvider

来源:互联网 发布:淘宝店工商执照 编辑:程序博客网 时间:2024/06/03 16:05

一、ContentProvider简介
    当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferencesAPI读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
二、Uri类简介
    Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:
    1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。
    2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
    3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
      •要操作contact表中id为10的记录,可以构建这样的路径:/contact/10
      •要操作contact表中id为10的记录的name字段, contact/10/name
      •要操作contact表中的所有记录,可以构建这样的路径:/contact
要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")
三、UriMatcher、ContentUrist和ContentResolver简介
    因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。
    UriMatcher:用于匹配Uri,它的用法如下:
    1.首先把你需要匹配Uri路径全部给注册上,如下:
    //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
    UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    //如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回匹配码为1
    uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
    //如果match()方法匹配   content://com.changcheng.sqlite.provider.contactprovider/contact/230路径,返回匹配码为2
    uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#号为通配符
    2.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回的匹配码为1。
    ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
    •withAppendedId(uri, id)用于为路径加上ID部分
    •parseId(uri)方法用于从路径中获取ID部分
    ContentResolver:当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。

 

什么是ContentUris?

ContentUris是content URI的一个辅助类。它有两个方法很有用,具体如下所示。

public static Uri withAppendedId(Uri contentUri, long id),这个方法负责把id和contentUri连接成一个新的Uri。比如在我们这个例子当中是这么使用 的:ContentUris.withAppendedId (Diary. DiaryColumns.CONTENT_URI, rowId)。如果rowId为100的话,那么现在的这个Uri的内容就是:
content://com.ex09_2_contentprovider.diarycontentprovider/diaries/100。

public static long parseId(Uri contentUri),这个方法负责把content URI 后边的id解析出来,比如现在这个content URI 是content://com.ex09_2_contentprovider.diarycontentprovider/diaries/100,那 么这个函数的返回值就是100。

 1. NotePad.java

public class NotePad { public static final String AUTHORITY = "com.xh.google.provider.NotePad";public static final class Notes implements BaseColumns{ //CONTENT_URI指到表public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";public static final String CONTENT_ITME_TYPE = "vnd.android.cursor.item/vnd.google.note";public static final String DEFAULT_SORT_ORDER = "modified DESC";public static final String TITLE = "title";public static final String NOTE = "note"; public static final String CREATEDDATE = "created";public static final String MODIFIEDDATE = "modified"; }}

2. NotePadProvider.java

public class NotePadProvider extends ContentProvider{private SQLiteDatabase db; private static final String DATABASE_NAME = "note_pad.db";   //数据库名字private static final int DATABASE_VERSION = 2;private static final String NOTES_TABLE_NAME = "notes";   //表的名字//创建表的SQL语句private static final String CREATE_TABLE="CREATE TABLE " + NOTES_TABLE_NAME + "(" + Notes._ID + "INTEGER PRIMARY KEY,"+ Notes.TITLE + " TEXT," + Notes.NOTE+ " TEXT," + Notes.CREATEDDATE + " INTEGER,"+ Notes.MODIFIEDDATE + " INTEGER" + "); ";private static final UriMatcher sUriMatcher; private static final int NOTES = 1; private static final int NOTE_ID = 2; private static HashMap<String, String> sNotesProjectionMap;static{ sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); sNotesProjectionMap = new HashMap<String, String>();sNotesProjectionMap.put(Notes._ID, Notes._ID);sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE); sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE); }private DatabaseHelper mOpenHelper; private static class DatabaseHelper extends SQLiteOpenHelper{ DatabaseHelper(Context context){super(context, DATABASE_NAME, null, DATABASE_VERSION); }@Overridepublic void onCreate(SQLiteDatabase arg0) {// TODO Auto-generated method stub//创建数据库表arg0.execSQL(CREATE_TABLE);}@Overridepublic void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {// TODO Auto-generated method stubarg0.execSQL("DROP TABLE IF EXISTS notes"); onCreate(arg0);}}@Override//创建数据库表,并获取数据库句柄public boolean onCreate() {// TODO Auto-generated method stubmOpenHelper = new DatabaseHelper(getContext()); db = mOpenHelper.getWritableDatabase();return true;}@Override//向数据库表插入一条记录public Uri insert(Uri uri, ContentValues initialValues) {// TODO Auto-generated method stubif (sUriMatcher.match(uri) != NOTES) { throw new IllegalArgumentException("Unknown URI " + uri); }ContentValues values; if (initialValues != null) { values = new ContentValues(initialValues); }else { values = new ContentValues(); }Long now = Long.valueOf(java.lang.System.currentTimeMillis()); if (values.containsKey(NotePad.Notes.CREATEDDATE) == false) { values.put(NotePad.Notes.CREATEDDATE, now);}if (values.containsKey(NotePad.Notes.MODIFIEDDATE) == false) { values.put(NotePad.Notes.MODIFIEDDATE, now); }if (values.containsKey(NotePad.Notes.TITLE) == false) { Resources r = Resources.getSystem();values.put(NotePad.Notes.TITLE, r.getString(android.R.string.unknownName)); }if (values.containsKey(NotePad.Notes.NOTE) == false) { values.put(NotePad.Notes.NOTE, ""); }long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); if (rowId > 0) { //负责把/rowId追加到CONTENT_URI的后面,连接成一个新的uriUri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);getContext().getContentResolver().notifyChange(noteUri, null);return noteUri; }throw new SQLException("Failed to insert row into" + uri); }@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {// TODO Auto-generated method stubint count; switch (sUriMatcher.match(uri)) {case NOTES:count = db.delete(NOTES_TABLE_NAME, selection, selectionArgs); break;case NOTE_ID: {String noteId = uri.getPathSegments().get(1);  count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);break;}default: throw new IllegalArgumentException("Unnown URI" + uri); }getContext().getContentResolver().notifyChange(uri, null);  return count;}@Overridepublic String getType(Uri arg0) {// TODO Auto-generated method stubreturn null;}@Override//selection是条件语句public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) {// TODO Auto-generated method stub/*Cursor cursor; switch(sUriMatcher.match(uri)) {case NOTES:cursor= db.query(NOTES_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);break;case NOTE_ID:long id=ContentUris.parseId(uri);String myselection="_id="+id; if(selection!=null){myselection +=selection;}cursor =db.query(NOTES_TABLE_NAME, projection, myselection, selectionArgs, null, null, sortOrder);break;default:  throw new IllegalArgumentException("Unknown URI " + uri); }return cursor;*/SQLiteQueryBuilder qb = new SQLiteQueryBuilder();  switch (sUriMatcher.match(uri)) {case NOTES:qb.setTables(NOTES_TABLE_NAME);  qb.setProjectionMap(sNotesProjectionMap); break; case NOTE_ID: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap);  qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1)); break; default:  throw new IllegalArgumentException("Unknown URI " + uri); }String orderBy;if (TextUtils.isEmpty(sortOrder)) {orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;}else{orderBy = sortOrder; }Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);c.setNotificationUri(getContext().getContentResolver(), uri); return c;}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {// TODO Auto-generated method stubint count; switch (sUriMatcher.match(uri)) { case NOTES:count = db.update(NOTES_TABLE_NAME, values, selection, selectionArgs); break;case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);break; default: throw new IllegalArgumentException("Unknow URI " + uri);  }return count;}}

3. MainActivity.java

public class MainActivity extends Activity {private TextView mView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mView=(TextView)this.findViewById(R.id.textView1);//向数据库表插入一条记录//NotePad.Notes.CONTENT_URI指到的是一个数据库表ContentValues values = new ContentValues(); values.put(NotePad.Notes.TITLE, "title1"); values.put(NotePad.Notes.NOTE, "NOTENOTE1");  getContentResolver().insert(NotePad.Notes.CONTENT_URI, values);values.clear(); values.put(NotePad.Notes.TITLE, "title2"); values.put(NotePad.Notes.NOTE, "NOTENOTE2");  getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); displayNote(); }private void displayNote(){/*Context ctx = MainActivity.this;ContentResolver resolver = ctx.getContentResolver();Cursor c = resolver.query(NotePad.Notes.CONTENT_URI, null, null, null, null);c.moveToFirst();for(int i=0; i<c.getCount(); i++){//NotePad.Notes.TITLE是一个数据库表的字段名,index是该字段的索引int index = c.getColumnIndexOrThrow(NotePad.Notes.TITLE);String src = c.getString(index);c.moveToNext();mView.setText("NOTE:"+src);}*/String columns[] = new String[] { NotePad.Notes.TITLE,NotePad.Notes.NOTE,NotePad.Notes.CREATEDDATE,NotePad.Notes.MODIFIEDDATE}; Uri myUri = NotePad.Notes.CONTENT_URI; Cursor cur = managedQuery(myUri, columns, null, null, null); if (cur.moveToFirst()) { String note = null; String titile = null; do { note = cur.getString(cur.getColumnIndex(NotePad.Notes.NOTE)); titile = cur.getString(cur.getColumnIndex(NotePad.Notes.TITLE));/*Toast toast = Toast.makeText(this, "TITILE:"+id + "\t" + "NOTE:" + titile, Toast.LENGTH_LONG);toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 40);toast.show();*/mView.setText("TITILE:"+titile + "\n" + "NOTE:" + note);}while (cur.moveToNext()); }}}


 

0 0