android--创建自己的内容提供器

想要实现跨程序共享数据需要用到内容提供器,内容提供器给别的应用提供了访问接口,可以新建一个类去继承ContentProvider来创建一个自己的内容提供器。ContentProvider类中有6种抽象方法,在使用子类继承的时候需要全部重写。

 1 public class Myprovider extends ContentProvider {
 2 
 3     @Override
 4     /*
 5     初始化时调用
 6     通常会在这里完成对数据库的创建和升级等操作,返回true表示初始化成功。
 7     只有当存在ContentResolver尝试访问程序中的数据时,才会进行初始化。
 8      */
 9     public boolean onCreate() {
10         return false;
11     }
12 
13     /*
14     查询数据
15     uri 确定查询的是那一张表
16     projection 查询那一列
17     selection 和 selectionArgs查询那些行
18     sortOrder 对结果进行排序
19     返回的数据存放在Cursor对象中
20      */
21     @Override
22     public Cursor query(Uri uri,  String[] projection,  String selection,  String[] selectionArgs,  String sortOrder) {
23         return null;
24     }
25 
26     /*
27     根据传入的数据URI来返回相应的MIME类型
28      */
29     @Override
30     public String getType(Uri uri) {
31         return null;
32     }
33     /*
34     添加数据
35     uri 确定添加的是那一张表
36     values 保存待添加的数据
37     返回一条表示这条新记录的URI
38      */
39     @Override
40     public Uri insert(Uri uri,  ContentValues values) {
41         return null;
42     }
43     /*
44     删除数据
45     selection 和 selectionArgs 删除那些行
46     返回被删除的行数
47      */
48     @Override
49     public int delete(Uri uri,  String selection,  String[] selectionArgs) {
50         return 0;
51     }
52     /*
53     更新已有的数据
54     uri 确定更新的是那一张表
55     values 新数据
56     selection 和 selectionArgs 更新那些行
57     会返回更新的行数
58      */
59     @Override
60     public int update(Uri uri,  ContentValues values,  String selection,  String[] selectionArgs) {
61         return 0;
62     }
63 
64 }

  一个标准的内容URI写法是这样的:

  content://com.example.app.providder/table1

  这就表示想要访问com.example.app这个应用中的table1表中的数据

  content://com.example.app.providder/table1/1

  这表示想要访问com.example.app这个应用中的table1表中的id为1的数据

  content://com.example.app.providder/*

  这表示想要访问com.example.app这个应用中的任意表

  content://com.example.app.providder/table1/#

  这表示想要访问com.example.app这个应用中的table1表中的任意行的数据

  其中 * 表示任意长度的任意字符  # 表示任意长度的数字

  然后使用UriMatcher这个类实现匹配内容URI的功能,UriMatcher中有一个addURI()的方法,3个参数,可以分别把authority、path、和一个自定义代码,当调用UriMatcher的match()方法是,将一个URI传入,返回值某个能够匹配这个URI的自定义代码。

  修改后的代码:

  

 1 public class Myprovider extends ContentProvider {
 2 
 3     //用于识别URI的自定义代码
 4     public static final int TABLE1_DIR = 0;
 5 
 6     public static final int TABLE1_ITEM = 1;
 7 
 8     public static final int TABLE2_DIR = 2;
 9 
10     public static final int TABLE2_ITEM = 3;
11 
12     //创建UriMatcher的实例
13     private static UriMatcher uriMatcher;
14 
15     //将自定义代码和希望的URI匹配
16     static {
17         uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
18         uriMatcher.addURI("xbt.exp11.provider","table1",TABLE1_DIR);
19         uriMatcher.addURI("xbt.exp11.provider","table1/#",TABLE1_ITEM);
20         uriMatcher.addURI("xbt.exp11.provider","table2",TABLE2_DIR);
21         uriMatcher.addURI("xbt.exp11.provider","table2/#",TABLE2_ITEM);
22 
23     }
24     ...
25     /*
26     查询数据
27     uri 确定查询的是那一张表
28     projection 查询那一列
29     selection 和 selectionArgs查询那些行
30     sortOrder 对结果进行排序
31     返回的数据存放在Cursor对象中
32      */
33     @Override
34     public Cursor query(Uri uri,  String[] projection,  String selection,  String[] selectionArgs,  String sortOrder) {
35 
36         //判断希望被访问的数据是什么数据
37         switch (uriMatcher.match(uri)){
38             case TABLE1_DIR:
39                 //查询table1表中的所有数据
40                 break;
41             case TABLE1_ITEM:
42                 //查询table1表中的单条数据
43                 break;
44             case TABLE2_DIR:
45                 //查询table2表中的所有数据
46                 break;
47             case TABLE2_ITEM:
48                 //查询table2表中的单条数据
49                 break;
50             default:
51                 break;
52         }
53         ...
54     }
55 
56     ...
57 
58 }

  insert()、update()、delete()也可以使用switch (uriMatcher.match(uri)){..}这样的判断语句判断出希望访问的是那张表,再进行相应的操作

  getType()方法是一个所有的内容提供器都必须提供的一个方法,用于获取Uri对象所对应的MIME类型。

  一个内容URI所对应的MIME字符串主要由3部分组成,android的格式规定是:

  1、必须以vnd开头

  2、如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/

  3、最后接上vnd.<authority>.<path>

  所以,对于content://com.example.app.providder/table1这个内容URI,它所对应的MIME类型就可以写成:

  vnd.android.cursor.dir/vnd.example.app.providder.table1

  对于content://com.example.app.providder/table1/1这个内容URI,它所对应的MIME类型就可以写成:

  vnd.android.cursor..item/vnd.example.app.providder.table1

  实现getType()方法的逻辑如下:

public class Myprovider extends ContentProvider {

...

    /*
    根据传入的数据URI来返回相应的MIME类型
     */
    @Override
    public String getType(Uri uri) {
        
        switch (uriMatcher.match(uri)){
            case TABLE1_DIR:
                return "vnd.android.cursor.dir/vnd.xbt.exp11.provider.table1";
            case TABLE1_ITEM:
                return "vnd.android.cursor.item/vnd.xbt.exp11.provider.table1";
            case TABLE2_DIR:
                return "vnd.android.cursor.dir/vnd.xbt.exp11.provider.table2";
            case TABLE2_ITEM:
                return "vnd.android.cursor.item/vnd.xbt.exp11.provider.table2";
            default:
                break;
        }
        return null;
    }
}
原文地址:https://www.cnblogs.com/xxbbtt/p/7429380.html