android使用ContentProvider.doc_第1页
android使用ContentProvider.doc_第2页
android使用ContentProvider.doc_第3页
android使用ContentProvider.doc_第4页
android使用ContentProvider.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用 ContentProvider 共享数据 1. 统一的数据访问方式 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。 文件的操作模式中,通过指定文件的操作模式为Context.MODE_WORLD_READABLE 或Context.MODE_WORLD_WRITEABLE同样可以对外共享数据, 但数据的访问方式会因数据存储的方式而不同,如:采用xml文件对外共享数据,需要进行xml解析来读写数据; 采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。 而使用ContentProvider共享数据的好处是统一了数据访问方式。 通俗一点,例如我要访问另一个应用怎么来描述我的需求呢?有种方式可向 Webservice 那样,统一一种描述语言,大家靠这个来互相理解。但是太麻烦了。现在的情况远远好于应用 Webservice 的场景,因为,应用们都在一部手机上,大家都归 Android 操作系统老大管。于是好办! 甲应用说中文,说:我想得到联系人“13999999” 的详细信息。 乙应用来做大洋彼岸,说:I want to get contacts, 13999999r for more information. 丁说ri语,高呼呀嘛蝶。 这是在要求访问“通讯录”应用啊,是属于另一个应用了,在另一个进程里。难道我做一个“通信录”程序,为了要让别人访问我,我还得提供“中文”、“英文”、“ri文”三种访问模式?这没法搞了,于是由 Android 牵头,大家商议统一描述语言,于是弄出个 Uri。 那么以后这种需求 Android 规定,大家统一说一样的语言:content:/com.android.contacts/data/phones/filter/13999999 “通讯录”程序中需要提供一种对指定模式的 Uri 的解析机制,并且这种解析机制要注册在操作系统中,随时工作。 例如,只要解析到了“data/phones/filter/13999999” 这种模式,它立马截取出 “13999999” 然后再自己的持久化库中去找寻详细信息,再返回回去。2. 继承 ContentProviter public class PersonContentProvider extends ContentProvider;和 Activity 一样, ContentProviter 属于 Android 的一种组件3. 注册内容提供者 AndroidManifest.xml android:name : 指向内容提供者的类 android:authorities : 应用中的一个唯一的字符串标识。可以将它看作域名。在本应用或其它应用中,可以通过这个域名来访问内容提供者。4. ContentProvider 中的方法 /* * 其它应用可以通过此方法对内容提供者删除数据 */ public int delete(Uri uri, String selection, String selectionArgs) return 0; /* * 其它应用可以通过此方法对内容提供者添加数据 */ public Uri insert(Uri uri, ContentValues contentValues) /* * 其它应用可以通过此方法对内容提供者查询数据 */ public Cursor query(Uri uri, String arg1, String arg2, String arg3, String arg4) /* * 其它应用可以通过此方法对内容提供者更新数据 */ public int update(Uri arg0, ContentValues arg1, String arg2, String arg3) /* * 内容类型 */ public String getType(Uri uri) : 该方法用于返回当前Url所代表数据的MIME类型。 如果操作的数据属于集合类型, 那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有person记录的Uri为content:/vider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为10的person记录,Uri为content:/vider.personprovider/person/10, 那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。5. URI Uri代表了要操作的数据,Uri主要包含了两部分信息: 1. 需要操作的ContentProvider 2. 对ContentProvider中的什么数据进行操作, 一个 Uri 由以下几部分组成 scheme - content:/ (此 scheme 仅表示内容提供者的 scheme) 主机名或 Authority - vider.personprovider 路径 - person/10/name 组合成一个完整的 Uri 为:content:/vider.personprovider/person/10/name 路径虽然可以随便定义,但为了方便其它人理解,应该遵循一定的命名规则: 要操作person表中id为10的记录,可以构建这样的路径:/person/10 要操作person表中id为10的记录的name字段, person/10/name 要操作person表中的所有记录,可以构建这样的路径:/person 要操作xxx表中的记录,可以构建这样的路径:/xxx 当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下: 要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name 将字符串转换成Uri,可以使用Uri类中的parse()方法,如下: Uri uri = Uri.parse(content:/vider.personprovider/person) UriMatcher : 用于 Uri 匹配 UriMatcher.addURI : 添加一个 Uri 匹配模式 UriMatcher,match : 匹配Uri , 返回 Boolean 。 ContentUris :用于对 uri 进行字符操作 ContentUris.withAppendedId(uri, append) : 给 uri 添加一个 ID ContentUris.parseId : 从 Uri 中解析出 ID6. ContentResolver : 用于操作 ContentProvider 当外部应用需要对 ContentProvider 中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成, 要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法: 该方法用于往ContentProvider添加数据: public Uri insert(Uri uri, ContentValues values) 该方法用于从ContentProvider删除数据: public int delete(Uri uri, String selection, String selectionArgs) 该方法用于更新ContentProvider中的数据。 public int update(Uri uri, ContentValues values, String selection, String selectionArgs) 该方法用于从ContentProvider中获取数据。 public Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder) 这些方法的第一个参数为Uri, 代表要操作的ContentProvider和对其中的什么数据进行操作, 假设给定的是: Uri.parse(“content:/viders.personprovider/person/10”), 那么将会对主机名为viders.personprovider的ContentProvider进行操作, 操作的数据为person表中id为10的记录。 其中主机名是要访问的应用在 AndroidManifest.xml 所注册的 provider 的 authorities 属性7. 代码示例:应用一:内容提供者所在的应用1, AndroidManifest.xml provider android:name=.PersonContentProvider android:authorities=vider.personprovider / 2. 准备:数据库(这只是内容提供者的一种形式,还可以是操作文件,如 XML 等等) public class DBOpenHandler extends SQLiteOpenHelper /* * param context 当前应用上下文 */public DBOpenHandler(Context context) super(context, myAndroid.db, null, 2);Overridepublic void onCreate(SQLiteDatabase db) String sql_createTable = CREATE TABLE person (personid integer primary key autoincrement, name);db.execSQL(sql_createTable);Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) String sql = ALTER TABLE person ADD phone;db.execSQL(sql);db.execSQL(ALTER TABLE person ADD amount integer); 3. TContentProvider /* * 内容提供者 */public class PersonContentProvider extends ContentProvider private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);private static final int PERSONS = 1;private static final int PERSON = 2;private DBOpenHandler dbOpenHandler;/ 静态初始化 Uri 匹配模式static / content:/vider.personprovider/person : 表示对 person 表所有数据进行操作MATCHER.addURI(vider.personprovider, person, PERSONS);/ content:/vider.personprovider/person/3 : 表示对 Perosn 表 Id 为 3 的单体记录进行操作MATCHER.addURI(vider.personprovider, person/#, PERSON);/* * 其它应用可以通过此方法对内容提供者删除数据 */public int delete(Uri uri, String selection, String selectionArgs) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();int num = 0;switch (MATCHER.match(uri) case PERSONS :num = db.delete(person, selection, selectionArgs);break;case PERSON:long id = ContentUris.parseId(uri);String where =personid= + id;if(selection != null & !.equals(selection) where = where + and + selection;num = db.delete(person, where, selectionArgs);break;default :throw new IllegalArgumentException(Unkown Uri : + uri);return num;/* * 获取内容提供者内容的类型 */Overridepublic String getType(Uri uri) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();switch (MATCHER.match(uri) case PERSONS :/ vnd.android.cursor.dir : 集合类型return vnd.android.cursor.dir/person;case PERSON:/ vnd.android.cursor.item : 单条记录return vnd.android.cursor.item/person;default :throw new IllegalArgumentException(Unkown Uri : + uri);/* * 其它应用可以通过此方法对内容提供者添加数据 */public Uri insert(Uri uri, ContentValues contentValues) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();switch (MATCHER.match(uri) case PERSONS :long rowid = db.insert(person, name, contentValues);return ContentUris.withAppendedId(uri, rowid);default :throw new IllegalArgumentException(Unkown Uri : + uri);public boolean onCreate() dbOpenHandler = new DBOpenHandler(getContext();return true;/* * 其它应用可以通过此方法对内容提供者查询数据 */public Cursor query(Uri uri, String projection, String selection, String selectionArgs,String sortOrder) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();switch (MATCHER.match(uri) case PERSONS :return db.query(person, projection, selection, selectionArgs, null, null, sortOrder);case PERSON:long id = ContentUris.parseId(uri);String where =personid= + id;if(selection != null & !.equals(selection) where = where + and + selection;return db.query(person, projection, where, selectionArgs, null, null, sortOrder);default :throw new IllegalArgumentException(Unkown Uri : + uri);/* * 其它应用可以通过此方法对内容提供者更新数据 */public int update(Uri uri, ContentValues values, String selection, String selectionArgs) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();int num = 0;switch (MATCHER.match(uri) case PERSONS :num = db.update(person, values, selection, selectionArgs);break;case PERSON:long id = ContentUris.parseId(uri);String where =personid= + id;if(selection != null & !.equals(selection) where = where + and + selection;num = db.update(person, values, where, selectionArgs);break;default :throw new IllegalArgumentException(Unkown Uri : + uri);return num; 应用二:用于测试访问应用一的内容提供者1, AndroidManifest.xml 2,TestContentProvider : 测试类,测试访问应用一的内容提供者 public class TestContentProvider extends AndroidTestCase private static final String TAG = TestContentProvider;/* * 添加 */public void testSave() throws Throwable ContentResolver contentResolver = this.getContext().getContentResolver();String uriStr = content:/vider.personprovider/person;Uri uri = Uri.parse(uriStr);ContentValues values = new ContentValues();values.put(name, XXX);values.put(phone, 135123456);values.put(amount, 22222222222);uri = contentResolver.insert(uri, values );Log.i(TAG, uri.toString();/* * 更新 */public void testUpdate() throws Throwable ContentResolver contentResolver = this.getContext().getContentResolver();String uriStr = content:/vider.personprovider/person/3;Uri uri = Uri.parse(uriStr);ContentValues values = new ContentValues();values.put(name, XXX);values.put(phone, 135123456);values.put(amount, 4444444);contentResolver.update(uri, values, null, null);/* * 查找 */public void testFind() throws Throwable ContentResolver contentResolver = this.getContext().getContentResolver();String uriStr = content:/vider.personprovider/person;Uri uri = Uri.parse(uriStr);Cursor cursor = contentResolver.query(uri, null, null, null, personid asc);/ 打印在日志信息上while(cursor.moveToNext() int personId = cursor.getInt(cursor.getColumnIndex(name);String name = cursor.getString(cursor.getColumnIndex(name);String phone = cursor.getString(cursor.getColumnIndex(phone);int amount = cursor.getInt(cursor.getColumnIndex(amount);Log.i(TAG, Person amount= + amount + , id= + personId + , name= + name+ , phone= + phone + );/* * 删除 */public void testDelete() throws Throwable ContentResolver contentResolver = this.getContext().getContentResolver();String uriStr = content:/vider.personprovider/person/3;Uri uri = Uri.parse(uriStr);contentResolver.delete(uri, null, null); 8. 监听内容提供者的数据变化 1. 内容提供者在数据发送更新时,需要发出一条更新通知,来通知注册在此URI上的访问者。 getContext().getContentResolver().notifyChange(uri, null); 例:在上例中,为 insert、update、delete 方法执行成功后,发出更新通知 public Uri insert(Uri uri, ContentValues contentValues) SQLiteDatabase db = dbOpenHandler.getWritableDatabase();switch (MATCHER.match(uri) case PERSONS :long rowid = db.insert(person, name, contentValues);/ 由内容提供者发出内容更新的通知。getContext().getContentResolver().notifyChange(uri, null);return ContentUris.withAppendedId(uri, rowid);default :throw new IllegalArgumentException(Unkown Uri : + uri); 2. 访问者需要监听内容提供者的通知 需要调用 ContentResolver 的 registerContentObserver 方法来注册一个监听器 registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer) param uri :监听哪个 uri param notifyForDescendents : true param ContentObserver : 使用哪个监听器来处理更新事务 示例: public class OtherActivity extends Activity private static final String TAG = OtherActivity; Override public void onCreate(Bundle s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论