Android 四大组件之Content Provider
来源:互联网 发布:linux检查文件是否存在 编辑:程序博客网 时间:2024/05/17 08:57
ContentProvider的定义
为存储和获取数据提供统一的接口。可以在不同的应用程序之间共享数据。
ContentProvider提供的方法
- query:查询
- insert:插入
- update:更新
- delete:删除
- getType:得到数据类型
- onCreate:创建数据时调用的回调函数
ContentProvider的特点
1)、ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节。使用表的形式来组织数据。
2)、使用ContentProvider可以在不同的应用程序之间共享数据。
3)、Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。
Uri的介绍
用到ContentProvider 就不得不介绍一下Uri了 因为ContentProvider的对外提供的数据就是用URI形式体现的。
Uri代表了要操作的数据,Uri主要包含了两部分信息:
1、需要操作的ContentProvider ,
2、对ContentProvider中的什么数据进行操作,
例如:content://com.zhi.example.myprovider/tablename/id
一个Uri由以下几部分组成:
1. 标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;”content://”
2. URI 的标识,用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。它定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在元素的authorities属性中说明:一般是定义该ContentProvider的包.类的名称。 例如:com.zhi.contentprovider.mycontentprovider
3. 路径(path),通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了;”content://com.zhi.contentprovider.mycontentprovider/tablename”
4. 如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部;
“content://com.zhi.contentprovider.mycontentprovider/tablename/#” #表示数据id。
另外:
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作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://com.zhi.contentprovider.mycontentprovider/person”)
UriMatcher类
Uri代表了要操作的数据,所以我们需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。掌握它们的使用,会便于我们的开发工作。
UriMatcher类用于匹配Uri,它的用法如下:
1、 初始化
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
2、 注册需要的Uri
matcher.addURI("com.zhi.mycontentprovider", "people", PEOPLE); matcher.addURI("com.zhi.mycontentprovider", "person/#", PEOPLE_ID);
3、 对已经注册的Uri进行匹配:
Uri uri = Uri.parse("content://" + "com.zhi.mycontentprovider" + "/people"); //匹配,并得到返回码int match = matcher.match(uri); //对返回码进行分析,返回响应的Uri;switch (match) { case PEOPLE: return "vnd.android.cursor.dir/people"; case PEOPLE_ID: return "vnd.android.cursor.item/people"; default: return null; }
ContentUris类
ContentUris类用于操作Uri路径后面的ID部分,它有两个比较实用的方法
1、public static Uri withAppendedId(Uri contentUri, long id)
这个方法负责把id和contentUri连接成一个新的Uri。
例如 contentUri为content://com.bing.provider.personprovider/person
id为10
那么使用这个方法返回的新的Uri的值为content://com.zhi.mycontentprovider/person/10
2、 public static long parseId(Uri contentUri)
这个方法负责把content URI 后边的id解析出来,比如现在这个content URI 是content://com.zhi.mycontentprovider/person/10,
那么这个函数的返回值就是10。
如何使用ContentProvider
1、自定义一个类,继承SQLiteOpenHelper,并实现数据库的创建
2、自定义一个类,继承ContentProvider ,实现数据的增删查更新等操作。
3、在Activity获取一个ContentResolver实例 ,用ContentResolver来管理ContentProvider,
4、在AndroidManifest.xml中注册自定义的ContentProvider 类
下面通过一个自己test的例子来说明一下:
实现一个类DatabaseHelper继承SQLiteOpenHelper
package com.zhi.contentprovider;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import com.zhi.contentprovider.Provider.PersonColumns;/** * SQL数据库的创建 * @author zhi * */public class DatabaseHelper extends SQLiteOpenHelper { //数据库的名称 private final static String DATABASE_NAME="dbZhi.db"; //数据库的版本号 private final static int DATABASE_VERSION =1; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub //创建一个Person的表 db.execSQL("CREATE TABLE " + PersonColumns.TABLE_NAME + " (" + PersonColumns._ID + " INTEGER PRIMARY KEY," + PersonColumns.NAME + " TEXT," + PersonColumns.AGE + " INTEGER" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub //当有数据库更新时,删掉这个表,并重新创建(注意,在实际编程中,存在表中的数据一般都是重要的,不能这删除表,应该在现有表的基础上增加字段等操作) db.execSQL("DROP TABLE IF EXISTS " + PersonColumns.TABLE_NAME); onCreate(db); }}
实现一个类PersionProvide继承ContentProvider
package com.zhi.contentprovider;import java.util.HashMap;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.text.TextUtils;/** * 内容提供者组件 * @author zhi * */public class PersionProvide extends ContentProvider { //声明一个集合变量 private static HashMap<String, String> sPersonsProjectionMap; //创建代号 private static final int PERSONS = 1; private static final int PERSONS_ID = 2; private static final UriMatcher sUriMatcher; private DatabaseHelper mOpenHelper; @Override public boolean onCreate() { // TODO Auto-generated method stub //初始化一个DatabaseHelper实例 mOpenHelper=new DatabaseHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub //查询操作 return null; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub //返回数据类型 switch (sUriMatcher.match(uri)) { case PERSONS: return Provider.CONTENT_TYPE; case PERSONS_ID: return Provider.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub //插入数据 if (sUriMatcher.match(uri) != PERSONS) { throw new IllegalArgumentException("Unknown URI " + uri); } ContentValues values2 = null; if (null!=values) { values2=new ContentValues(values); }else { values=new ContentValues(); } // Make sure that the fields are all set if (values2.containsKey(Provider.PersonColumns.NAME) == false) { values2.put(Provider.PersonColumns.NAME, ""); } if (values2.containsKey(Provider.PersonColumns.AGE) == false) { values2.put(Provider.PersonColumns.AGE, 0); } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(Provider.PersonColumns.TABLE_NAME, Provider.PersonColumns.NAME, values2); if (rowId > 0) { Uri noteUri = ContentUris.withAppendedId(Provider.PersonColumns.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into " + uri); } @Override public int delete(Uri uri, String where, String[] whereArgs) { // TODO Auto-generated method stub //删除数据 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case PERSONS: count = db.delete(Provider.PersonColumns.TABLE_NAME, where, whereArgs); break; case PERSONS_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(Provider.PersonColumns.TABLE_NAME, Provider.PersonColumns._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { // TODO Auto-generated method stub //更新数据 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case PERSONS: count = db.update(Provider.PersonColumns.TABLE_NAME, values, where, whereArgs); break; case PERSONS_ID: String noteId = uri.getPathSegments().get(1); count = db.update(Provider.PersonColumns.TABLE_NAME, values, Provider.PersonColumns._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 这个地方的persons要和PersonColumns.CONTENT_URI中最后面的一个Segment一致 sUriMatcher.addURI(Provider.AUTHORITY, "persons", PERSONS); sUriMatcher.addURI(Provider.AUTHORITY, "persons/#", PERSONS_ID); sPersonsProjectionMap = new HashMap<String, String>(); sPersonsProjectionMap.put(Provider.PersonColumns._ID, Provider.PersonColumns._ID); sPersonsProjectionMap.put(Provider.PersonColumns.NAME, Provider.PersonColumns.NAME); sPersonsProjectionMap.put(Provider.PersonColumns.AGE, Provider.PersonColumns.AGE); } }
- Android四大组件之Content Provider
- Android四大基本组件之Content Provider
- Android四大组件之Content Provider
- Android四大组件之Content Provider
- Android 四大组件之 Content Provider
- Android 四大组件之Content provider使用
- Android四大组件之自定义Content Provider
- Android 四大组件之Content Provider
- Android四大组件之Content Provider
- Android四大组件之Content Provider
- Android四大组件之Content Provider
- android的四大组件之Content Provider
- 四大组件之Content Provider
- Android 四大组件 之 content provider 创建流程
- Android四大组件之Content Provider(内容提供者)
- Android四大组件之 内容提供器Content Provider
- Android笔记---四大组件之Content Provider内容提供者详解
- Android四大组件之内容提供者Content Provider总结
- laravel Model模型
- Producer/Consumer Model(pthread)
- js方法fromCharCode()实现中文字输出
- [2015年7月][6~10][解bug,算法学习]
- 分析Reporting Service的报表执行记录
- Android 四大组件之Content Provider
- emlog 如何插入百度统计代码
- Python笔记:multiprocessing模块详解
- 【C++基础】——const关键字
- LeetCode——Evaluate Reverse Polish Notation
- mysql学习笔记(一)
- IOS 屏幕尺寸、分辨率、点之间的相互关系
- java版排序算法简介及冒泡排序以及优化,选择排序,直接插入排序,希尔排序,堆排序,快速排序及其优化前言2 分类2 稳定性3 时间复杂度4 Java实现版本5 1、冒泡排序6 2、选择排序
- Rust中文翻译16