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


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

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

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

     

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

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

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

    1)ContentProvider:

    该类是一个抽象类,要在自己应用中使用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中的一个静态方法:

     

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

    4)UriMatcher:

     

    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进行操作的工具类

     

    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的简单使用。

  • 相关阅读:
    使用virtualenv搭建python3的环境
    Linux/unix inode
    转:进程间通信方式
    保研复试上机——数据库
    转:mysql grant
    mysql 查询结果创建表
    279. Perfect Squares
    Mybatis中javaType和jdbcType对应和CRUD例子
    mysql explain
    91. Decode Ways
  • 原文地址:https://www.cnblogs.com/dqrcsc/p/4638741.html
Copyright © 2020-2023  润新知