android-ContentProvider<七>
1.ContentProvider
Content Provider 作为Android应用程序四大组件之一,为存储和查询数据提供统一的接口,实现程序间
数据的共享。Android系统内一些常见的数据如音乐、视频、图像等都内置了一系列的Content Provider。
应用程序间共享数据有两种方式:
- 是创建子类继承于Content Provider,重写该类用于数据存储和查询的方法。(注意:这通常是为某类,设计它的CP)
- 是直接使用已经存在的Content Provider,如联系人等。
存储数据的方式:
在Content Provider中数据的是以表的形式存储,在数据表中每一行为一条记录,每一列为类型和数据。
每一条记录都包括一个唯一的名叫_ID的数值字段,这个字段唯一标识一条数据记录。
在创建表的时候用 INTEGER PRIMARY KEY AUTOINCREMENT来标识此字段。
意思是:这是主键,类型为int ,数值从1开始递增。下面就是将UserTableMetaData._ID这列设成这样
例如:db.execSQL("create table " + USERS_TABLE_NAME+ "("+UserTableMetaData._ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT,"+.UserTableMetaData.USER_NAME+" varchar(20));")
参考博客:http://blog.csdn.net/liuhe688/article/details/7050868
注意:
2.ContentProvider类的设计模式
成员变量(字段):
private static final UriMatcher matcher; private DBHelper helper; private SQLiteDatabase db; private static final String AUTHORITY = "com.scott.provider.PersonProvider"; private static final int PERSON_ALL = 0; private static final int PERSON_ONE = 1; public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.scott.person"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.scott.person"; //数据改变后立即重新查询 private static final Uri NOTIFY_URI = Uri.parse("content://" + AUTHORITY + "/persons"); static { matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI(AUTHORITY, "persons", PERSON_ALL); //匹配记录集合 matcher.addURI(AUTHORITY, "persons/#", PERSON_ONE); //匹配单条记录 }
成员方法(增删改查):
1 @Override 2 public boolean onCreate() { 3 helper = new DBHelper(getContext()); 4 return true; 5 } 6 7 @Override 8 public String getType(Uri uri) { 9 int match = matcher.match(uri); 10 switch (match) { 11 case PERSON_ALL: 12 return CONTENT_TYPE; 13 case PERSON_ONE: 14 return CONTENT_ITEM_TYPE; 15 default: 16 throw new IllegalArgumentException("Unknown URI: " + uri); 17 } 18 } 19 20 @Override 21 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 22 db = helper.getReadableDatabase(); 23 int match = matcher.match(uri); 24 switch (match) { 25 case PERSON_ALL: 26 //doesn't need any code in my provider. 27 break; 28 case PERSON_ONE: 29 long _id = ContentUris.parseId(uri); 30 selection = "_id = ?"; 31 selectionArgs = new String[]{String.valueOf(_id)}; 32 break; 33 default: 34 throw new IllegalArgumentException("Unknown URI: " + uri); 35 } 36 return db.query("person", projection, selection, selectionArgs, null, null, sortOrder); 37 } 38 39 @Override 40 public Uri insert(Uri uri, ContentValues values) { 41 int match = matcher.match(uri); 42 if (match != PERSON_ALL) { 43 throw new IllegalArgumentException("Wrong URI: " + uri); 44 } 45 db = helper.getWritableDatabase(); 46 if (values == null) { 47 values = new ContentValues(); 48 values.put("name", "no name"); 49 values.put("age", "1"); 50 values.put("info", "no info."); 51 } 52 long rowId = db.insert("person", null, values); 53 if (rowId > 0) { 54 notifyDataChanged(); 55 return ContentUris.withAppendedId(uri, rowId); 56 } 57 return null; 58 } 59 60 @Override 61 public int delete(Uri uri, String selection, String[] selectionArgs) { 62 db = helper.getWritableDatabase(); 63 int match = matcher.match(uri); 64 switch (match) { 65 case PERSON_ALL: 66 //doesn't need any code in my provider. 67 break; 68 case PERSON_ONE: 69 long _id = ContentUris.parseId(uri); 70 selection = "_id = ?"; 71 selectionArgs = new String[]{String.valueOf(_id)}; 72 } 73 int count = db.delete("person", selection, selectionArgs); 74 if (count > 0) { 75 notifyDataChanged(); 76 } 77 return count; 78 } 79 80 @Override 81 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 82 db = helper.getWritableDatabase(); 83 int match = matcher.match(uri); 84 switch (match) { 85 case PERSON_ALL: 86 //doesn't need any code in my provider. 87 break; 88 case PERSON_ONE: 89 long _id = ContentUris.parseId(uri); 90 selection = "_id = ?"; 91 selectionArgs = new String[]{String.valueOf(_id)}; 92 break; 93 default: 94 throw new IllegalArgumentException("Unknown URI: " + uri); 95 } 96 int count = db.update("person", values, selection, selectionArgs); 97 if (count > 0) { 98 notifyDataChanged(); 99 } 100 return count; 101 } 102 103 //通知指定URI数据已改变 104 private void notifyDataChanged() { 105 getContext().getContentResolver().notifyChange(NOTIFY_URI, null); 106 } 107 }
3.Uri类
用来指向操作的数据,一般为contentprovider的类下的表名(在数据库中已创建的某张表)
(构造)方法: public static Uri parse (String uriString)
String AUTHORIY = "mars.cp.FirstContentProvider";
Uri.parse("content://" + AUTHORIY + "/users");
4.UriMatcher类
它是用来匹配Uri的,因为Uri有可能是指向整张表(..../users,users为一张表明),
也有可能指向表中的某个记录(如:.../users/10,users表中的id为10的记录)。
注意:下面里的“#”为通配符,用来通配各种uri里指向的某条记录(../users/1,.../user/5,等等),起到了代表所有指向记录类型的uri.
1 public static final UriMatcher uriMatcher; 2 uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 3 uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users", 4 INCOMING_USER_COLLECTION); 5 uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users/#", 6 INCOMING_USER_SINGLE);
5.ContentUris类
通常使用它的withAppendedId方法,为指向整张表的Uri尾部添加指向id值。
String AUTHORIY = "mars.cp.FirstContentProvider"; Uri CONTENT_URI = Uri.parse("content://" + AUTHORIY + "/users"); Uri insertedUserUri = ContentUris.withAppendedId(CONTENT_URI, 10); //这里的insertedUserUri就成为了一个指向某张表下id=10的记录。