转载

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

ContentProvider是Android四大组件之一,它用来封装数据,并通过ContentResolver接口将数据提供给其他应用。只有当需要在多个应用之间共享数据时才会用到ContentProvider。

多个应用共享数据时,如何区分是哪个应用中的那部分数据呢?

ContentProvider通过Uri标识具体某个应用的某些数据。当一个应用提供了ContentProvider向其他应用共享数据时,该应用在其ContentProvider中添加标识自己特定数据的Uri,然后其他应用想要获得这些数据时,则可以通过向ContentResolver接口的方法传入标识要访问的数据的Uri即可。

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

如应用B和应用C都向外提供数据,他们就需要在自己提供的ContentProvider中分别指明自己所能解析的Uri。应用A要访问应用B和应用C提供的数据,就需要使用ContentResolver接口,要向该接口的访问数据的方法中传入特定的Uri以区分是要访问应用B的数据,还是要访问应用C的数据。

应用之间共享数据需要用到的类和接口有:ContentProvider、ContentResolver、Uri、UriMatcher、ContentUris等。

下面一一学习这几个类和接口的简单使用:

1)ContentProvider:

该类是一个抽象类,要在自己应用中使用ContentProvider对象,需要自定义类继承ContentProvider类,并实现几个主要的抽象方法:

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

onCreate()方法: 其它应用第一次访问该ContentProvider时被调。

insert()方法:外部应用使用此方法添加数据。

delete()方法:外部应用使用此方法删除数据。

update  ()方法:外部应用使用此方法更新数据。

query()方法:外部应用使用此方法查询数据。

getType()方法: 主要用于匹配数据类型,返回当前Uri所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/自定义类型。数据属于非集合类型数据,应该返回vnd.android.cursor.item/自定义类型。

2)ContentResolver:

是一个接口,可以通过Context.getContentResolver()获取该接口的实例,当在自己应用中要访问别的应用ContentProvider提供的数据时,需要获取该接口的实例,然后调用该接口的insert()、update()、query()、delete()等方法,最终会调用对应ContentProvider中同名的方法,实现共享数据的增删改查操作。

3)Uri:

也是一个抽象类。

Uri标准的格式是:schema://主机名authority/path[/ID]

后面的ID部分根据访问需要,可能没有。

如:content://cn.csc.app1/student标识要访问的是cn.csc.app1所标识的应用中的student表。

ContentProvider中Uri的schema部分一般为content://

authority用来标识要访问的是哪个ContentProvider,通常用能唯一标识应用的包名作为authority。

path部分,则标识我们要访问的是哪些数据,如student表示我们要访问的是student表的数据。

若加上ID部分,如content://cn.csc.app1/student/10,一般被用来表示我们要访问的是student表中的id为10的那条数据。

uri中可以使用通配符:

*:表示匹配任意长度的字符串

#:表示匹配任意长度的数字串

如匹配任意表的uri可以表示为:content://cn.csc.app1/*

匹配student表中任意一条记录的uri:content://cn.csc.app1/student/#

常用到的是Uri中的一个静态方法:

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

parse()用来将字符串表示的uri解析为Uri对象。

4)UriMatcher:

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

Uri匹配的一个工具类,一般用在ContentProvider中:

一般使用常量NO_MATCH作为参数,构造UriMatcher对象,然后调用addURI()方法向该对象中添加URI,使用match()方法判断传入的Uri的匹配结果。

addURI()方法的参数说明:

authority:Uri中的authority用于标识是哪个ContentProvider

path:Uri中的path部分,标识要操作的是哪张表

code:用于设置当前添加的Uri的标识码,当使用match方法,传入一个Uri参数时,会将匹配到的Uri对应的code返回,以指明当前匹配到哪个Uri。

5)ContentUris:

一个实用的对Uri进行操作的工具类

android菜鸟学习笔记21----ContentProvider(一)ContentProvider的简单使用

parseId():用来获取传入的Uri中的Id部分

withAppendId():用于将传入的Uri和id拼接起来。

下面是实际编写ContentProvider的一个简单示例:

第一步:要先有一个数据库帮助类,以便于进行数据库增删改查操作

 1 package cn.csc.content_provider.db;  2   3    4   5 import android.content.Context;  6   7 import android.database.sqlite.SQLiteDatabase;  8   9 import android.database.sqlite.SQLiteOpenHelper; 10  11 import android.database.sqlite.SQLiteDatabase.CursorFactory; 12  13 import android.util.Log; 14  15   16  17 public class MySqliteHelper extends SQLiteOpenHelper { 18  19       public static final String TAG = "MYSQLITEHELPER"; 20  21       public static final String CREATE_STUDENT = "create table t_student (" + 22  23                  "id integer primary key, name varchar(20), " + 24  25                  "gender varchar(10), age integer)"; 26  27       public static final String CREATE_TEACHER = "create table t_teacher(" + 28  29                  "id integer primary key, name varchar(20))"; 30  31       public MySqliteHelper(Context context, String name, CursorFactory factory, 32  33                  int version) { 34  35            super(context, name, factory, version); 36  37       } 38  39   40  41       @Override 42  43       public void onOpen(SQLiteDatabase db) { 44  45            Log.i(TAG,"open db"); 46  47            super.onOpen(db); 48  49       } 50  51   52  53       @Override 54  55       public void onCreate(SQLiteDatabase db) { 56  57            db.execSQL(CREATE_STUDENT); 58  59            db.execSQL(CREATE_TEACHER); 60  61       } 62  63   64  65       @Override 66  67       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 68  69   70  71       } 72  73 }

第二步:编写自己的ContentProvider类,继承自ContentProvider类,并实现主要的方法:

 1 1)编写MyContentProvider继承自ContentProvider类:  2   3 public class MyContentProvider extends ContentProvider {  4   5    6   7       @Override  8   9       public int delete (Uri uri, String selection, String[] selectionArgs) { 10  11            // TODO Auto-generated method stub 12  13            return 0; 14  15       } 16  17   18  19       @Override 20  21       public String getType(Uri uri) { 22  23            // TODO Auto-generated method stub 24  25            return null; 26  27       } 28  29   30  31       @Override 32  33       public Uri insert (Uri uri, ContentValues values){ 34  35            // TODO Auto-generated method stub 36  37            return null; 38  39       } 40  41   42  43       @Override 44  45       public boolean onCreate() { 46  47            // TODO Auto-generated method stub 48  49            return false; 50  51       } 52  53   54  55       @Override 56  57       public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 58  59            // TODO Auto-generated method stub 60  61            return null; 62  63       } 64  65   66  67       @Override 68  69       public int update (Uri uri, ContentValues values, String selection, String[] selectionArgs) { 70  71            // TODO Auto-generated method stub 72  73            return 0; 74  75       } 76  77 }

2)注意,四大组件都需要在Manifest.xml文件中注册:

在Application节点中添加:

1 <provider android:name="cn.csc.content_provider.MyContentProvider" 2  3             android:authorities="cn.csc.content_provider"></provider>

3)为该类添加一个静态UriMatcher字段,用于后续工作中Uri的匹配工作,并通过静态代码块,添加能够匹配的Uri:

 1 private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);  2   3       private static final int STUDENT_DIR = 0;  4   5       private static final int STUDENT_ITEM = 1;  6   7       private static final int TEACHER_DIR = 2;  8   9       private static final int TEACHER_ITEM = 3; 10  11       static{ 12  13            matcher.addURI("cn.csc.content_provider", "t_student", STUDENT_DIR); 14  15            matcher.addURI("cn.csc.content_provider", "t_student/#", STUDENT_ITEM); 16  17            matcher.addURI("cn.csc.content_provider", "t_teacher", TEACHER_DIR); 18  19            matcher.addURI("cn.csc.content_provider", "t_teacher/#", TEACHER_ITEM); 20  21       }

4)实现父类中的几个抽象方法:

  1 @Override   2    3       public int delete (Uri uri, String selection, String[] selectionArgs) {   4    5            int cnt = -1;   6    7            switch(matcher.match(uri)){   8    9            case STUDENT_DIR:  10   11                  cnt = db.delete("t_student", selection, selectionArgs);  12   13                  break;  14   15            case STUDENT_ITEM:  16   17                  long id = ContentUris.parseId(uri);  18   19                  cnt = db.delete("t_student", "id = ?", new String[]{id+""});  20   21                  break;  22   23            case TEACHER_DIR:  24   25                  cnt = db.delete("t_teacher", selection, selectionArgs);  26   27                  break;  28   29            case TEACHER_ITEM:  30   31                  long id1 = ContentUris.parseId(uri);  32   33                  cnt = db.delete("t_teacher", "id = ?", new String[]{id1+""});  34   35                  break;  36   37            }  38   39            return cnt;  40   41       }  42   43    44   45       @Override  46   47       public String getType(Uri uri) {  48   49            switch(matcher.match(uri)){  50   51            case STUDENT_ITEM:  52   53                  return "vnd.android.cursor.item/student";  54   55            case TEACHER_ITEM:  56   57                  return "vnd.android.cursor.item/teacher";  58   59            case STUDENT_DIR:  60   61                  return "vnd.android.cursor.dir/student";  62   63            case TEACHER_DIR:  64   65                  return "vnd.android.cursor.dir/teacher";  66   67            }  68   69            return null;  70   71       }  72   73    74   75       @Override  76   77       public Uri insert (Uri uri, ContentValues values){  78   79             80   81            switch(matcher.match(uri)){  82   83            case STUDENT_DIR:  84   85                  long id = db.insert("t_student", null, values);  86   87                  return ContentUris.withAppendedId(uri, id);  88   89            case TEACHER_DIR:  90   91                  return ContentUris.withAppendedId(uri, db.insert("t_teacher", null, values));  92   93            }  94   95            return null;  96   97       }  98   99   100  101       @Override 102  103       public boolean onCreate() { 104  105            helper = new MySqliteHelper(getContext(), "students.db", null, 1); 106  107            db = helper.getWritableDatabase(); 108  109            return true; 110  111       } 112  113   114  115       @Override 116  117       public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 118  119            Cursor cursor = null; 120  121            switch (matcher.match(uri)) { 122  123            case STUDENT_ITEM: 124  125                  long id = ContentUris.parseId(uri); 126  127                  cursor = db.query("t_student", projection, "id = ?", new String[]{id+""}, null, null, sortOrder); 128  129                  break; 130  131            case TEACHER_ITEM: 132  133                  long id1 = ContentUris.parseId(uri); 134  135                  cursor = db.query("t_teacher", projection, "id = ?", new String[]{id1+""}, null, null, sortOrder); 136  137                  break; 138  139            case STUDENT_DIR: 140  141                  cursor = db.query("t_student", projection, selection, selectionArgs, null, null, sortOrder); 142  143                  break; 144  145            case TEACHER_DIR: 146  147                  cursor = db.query("t_teacher", projection, selection, selectionArgs, null, null, sortOrder); 148  149                  break; 150  151            } 152  153            return cursor; 154  155       } 156  157   158  159       @Override 160  161       public int update (Uri uri, ContentValues values, String selection, String[] selectionArgs) { 162  163            int cnt = -1; 164  165            switch (matcher.match(uri)) { 166  167            case STUDENT_ITEM: 168  169                  long id = ContentUris.parseId(uri); 170  171                  cnt = db.update("t_student", values, "id = ?", new String[]{id+""}); 172  173                  break; 174  175            case TEACHER_ITEM: 176  177                  long id1 = ContentUris.parseId(uri); 178  179                  cnt = db.update("t_teacher", values, "id = ?", new String[]{id1+""}); 180  181                  break; 182  183            case STUDENT_DIR: 184  185                  cnt = db.update("t_student", values, selection, selectionArgs); 186  187                  break; 188  189            case TEACHER_DIR: 190  191                  cnt = db.update("t_teacher", values, selection, selectionArgs); 192  193                  break; 194  195            } 196  197            return cnt; 198  199       }

5)新建一个项目,在其中通过ContentResolver访问该ContentProvider提供的数据:

 1 public class MyTest extends AndroidTestCase {  2   3       public void testInsert(){  4   5            Uri uri = Uri.parse("content://cn.csc.content_provider/t_student");  6   7            ContentValues values = new ContentValues();  8   9            values.put("name", "dqrcsc"); 10  11            values.put("gender", "male"); 12  13            values.put("age", 24); 14  15            Uri uri2 = getContext().getContentResolver().insert(uri, values); 16  17            Log.i("Test",uri2.toString()); 18  19       } 20  21       public void testUpdate(){ 22  23            Uri uri = Uri.parse("content://cn.csc.content_provider/t_student/2"); 24  25            ContentValues values = new ContentValues(); 26  27            values.put("name", "bbbb"); 28  29            values.put("gender", "female"); 30  31            values.put("age", 12); 32  33            int i = getContext().getContentResolver().update(uri, values, null, null); 34  35            Log.i("Test",i+""); 36  37       } 38  39       public void testQuery(){ 40  41            Uri uri = Uri.parse("content://cn.csc.content_provider/t_student/3"); 42  43            Cursor cursor = getContext().getContentResolver().query(uri, new String[]{"id","name","gender","age"}, null, null, null); 44  45            while(cursor != null && cursor.moveToNext()){ 46  47                  Log.i("Test",cursor.getString(0)+","+cursor.getString(1)+","+cursor.getString(2)+","+cursor.getString(3)); 48  49            } 50  51       } 52  53       public void testQueryAll(){ 54  55            Uri uri = Uri.parse("content://cn.csc.content_provider/t_student"); 56  57            Cursor cursor = getContext().getContentResolver().query(uri, new String[]{"id","name","gender","age"}, null, null, null); 58  59            while(cursor != null && cursor.moveToNext()){ 60  61                  Log.i("Test",cursor.getString(0)+","+cursor.getString(1)+","+cursor.getString(2)+","+cursor.getString(3)); 62  63            } 64  65       } 66  67       public void testDelete(){ 68  69            Uri uri = Uri.parse("content://cn.csc.content_provider/t_student/6"); 70  71            int i = getContext().getContentResolver().delete(uri, null, null); 72  73            Log.i("Test",i+""); 74  75       } 76  77 }

以上,就是ContentProvider的简单使用。

正文到此结束
Loading...