安卓开发 四大组件之内容提供器

内容提供器使数据在不同的程序中实现共享

分类:

现有的内容提供器自定义的内容服务器

 

ContentResolver类

对于每个程序来说,如果想要访问内容提供器中的数据,一定要借助ContentResolver类,可以通过Context中的getContentResolver方法得到该类的实例。ContentResolver中提供了一系列的方法用于对数据进行CRUD操作。

ContentResolver中的增删改查方法接受的是Uri参数,被称为内容URI

由authority和path两部分组成

authority:一般包名.provider

path:表名

需要解析未Uri对象才可以作为参数传入

1.  如:Uri uri = uri.parse("content://com.example.app.provider/table1");  

查询

查询完成后返回的是一个Cursor对象,对Cursor对象进行遍历得到我们所需要的数据

1.  Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, orderBy)

1.  if (cursor != null){  

2.      while (cursor.moveToNext()){  

3.      String column1 = cursor.getString(cursor.getColumIndex("column1"));  

4.      int column2 = cursor.getInt(cursor.getColumIndex("column2"));  

5.      }  

6.  }  

 

添加

将待添加的数据组装到ContentValues中,再用insert

1.  ContentValues values = new ContentValues();  

2.  values.put("column1""text");  

3.  values.put("column2"1);  

4.  getContentResolver.insert(uri, values); 


更新

将待跟新的数据组装到ContentValues中,再update

1.  ContentValues values = new ContentValues();  

2.  values.put("column1""");  

3.  getContentResolver.update(uri, values, "column1 = ?"new String[] {"text" , "1"}); 

 

删除

1.  getContentResolver().delete(uri,”column2=”,newString[]{“1”});  


例子:查询手机中的通讯里(只给出查询代码,完整需要添加权限)

其中的uri被系统已经封装好的通讯的URI

1.  private void readContacts(){  

2.      Cursor cursor = null;  

3.      try{  

4.          //查询联系人数据  

5.          cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, nullnullnullnull);  

6.          while (cursor.moveToNext()) {  

7.              //获取联系人姓名  

8.              String displayName = cursor.getString(cursor.getColumnIndex(  

9.                      ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));  

10.             //获取联系人手机  

11.             String number = cursor.getString(cursor.getColumnIndex(  

12.                     ContactsContract.CommonDataKinds.Phone.NUMBER));  

13.             contactsList.add(displayName + "\n" + number);   

14.         }  

15.     }catch (Exception e){  

16.         e.printStackTrace();  

17.     }finally{  

18.         if (cursor != null){  

19.             cursor.close();  //别忘了关闭

20.         }  

21.     }  

22.    } 

 

自定义内容提供器

实现跨程序共享数据的功能,官方推荐的就是使用内容提供其,可以通过新建一个类去继承ContentProvider的方式来创建一个自己的内容提供器。

需要重写ContentProvider中的6个抽象方法

1.onCreate()

初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在 ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。

2.query()

从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于对结果进行排序,查询的结果存放在 Cursor 对象中返回。

3.insert()

向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。

4. update()

更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的行数将作为返回值返回。

5. delete()

从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。

6.getType()

根据传入的内容 URI 来返回相应的 MIME 类型。

getType()方法。它是所有的内容提供器都必 须提供的一个方法,用于获取Uri 对象所对应的 MIME 类型。一个内容 URI 所对应的 MIME 字符串主要由三部分组分,Android 对这三个部分做了如下格式规定。

1.   必须以 vnd 开头。

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

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

所以,对于 content://com.example.app.provider/table1 这个内容 URI,它所对应的 MIME

类型就可以写成:

vnd.android.cursor.dir/vnd.com.example.app.provider.table1

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

vnd.android.cursor.item/vnd.com.example.app.provider.table1

 

可以看到,几乎每一个方法都会带有 Uri 这个参数,这个参数也正是调用 ContentResolver的增删改查方法时传递过来的。而现在,我们需要对传入的 Uri 参数进行解析,从中分析出调用方期望访问的表和数据。

 

回顾一下,一个标准的内容 URI 写法是这样的:

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

这就表示调用方期望访问的是 com.example.app 这个应用的 table1 表中的数据。除此之外,我们还可以在这个内容 URI 的后面加上一个 id,如下所示:

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

这就表示调用方期望访问的是 com.example.app 这个应用的 table1 表中 id 为 1 的数据。内容 URI 的格式主要就只有以上两种,以路径结尾就表示期望访问该表中所有的数据,以 id 结尾就表示期望访问该表中拥有相应 id 的数据。我们可以使用通配符的方式来分别匹配这两种格式的内容 URI,规则如下。

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

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

所以,一个能够匹配任意表的内容 URI 格式就可以写成:

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

而一个能够匹配 table1 表中任意一行数据的内容 URI 格式就可以写成:

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

 

所以要使用UriMatcher来进行匹配,UriMatcher中提供了一个addURI方法,接受三个参数,authority,path,和一个自定义代码。倒是后匹配成功后返回的是这个自定义代码,利用这个代码就可以判断访问的是哪个表中的数据了

例子:

publicclassMyProvider extendsContentProvider {

publicstaticfinalintTABLE1_DIR = 0;

publicstaticfinalintTABLE1_ITEM = 1;

publicstaticfinalintTABLE2_DIR = 2;

publicstaticfinalintTABLE2_ITEM = 3;

privatestaticUriMatcher uriMatcher;static{

uriMatcher = newUriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI("com.example.app.provider","table1", TABLE1_DIR);

uriMatcher.addURI("com.example.app.provider ","table1/#", TABLE1_ITEM);

uriMatcher.addURI("com.example.app.provider ","table2", TABLE2_ITEM);

uriMatcher.addURI("com.example.app.provider ","table2/#", TABLE2_ITEM);

}

……

@Override

publicCursor query(Uri uri,String[] projection, String selection, String[] selectionArgs, StringsortOrder) {

switch(uriMatcher.match(uri)) {

caseTABLE1_DIR:

// 查询table1表中的所有数据

break;

caseTABLE1_ITEM:

// 查询table1表中的单条数据

break;

caseTABLE2_DIR:

// 查询table2表中的所有数据

break;

caseTABLE2_ITEM:

// 查询table2表中的单条数据

break;

default:

break;

}

……

}

……

}

 

总结:

以外部查询为例:

外部传入内容URI,自定义内容提供器中会再static初始化模块中新建一个uriMatcher对象,并且给他添加好对应关系。

在query方法中,会通过switch方法找出外部需要查询的表格。再进行操作

其他方法同理


第一行代码 例子https://blog.csdn.net/qq_31568297/article/details/52923870


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值