Android || ContentResolver && ContentProvider

1 背景

在 Android 官方指出的 Android的数据存储方式总共5种,分别为:

  • Shard Prederences;网络存储;文件存储;外储存储;SQLite

一般这些存储只是在单独的一个应用程序之中达到一个数据的共享,有时需要操作其他应用程序的一些数据。例如,我们需要操作系统里的媒体库、通讯录等,这是就可以通过 ContentProvider 来满足我们的需求。
当采用文件方式对外共享数据,需要进行文件操作读写数据;当采用 sharepreferences共享数据,需要其相应的 api读写数据。而采用 ContentProvider 共享数据,是统一了数据访问方式。

2 App间的数据获取

ContentProvider:组织应用的数据;向其他应用提供数据
ContentResolver:获取ContentProvider提供的数据;添加/删除/查询/修改数据等

  1. Android 是如何实现应用程序之间数据共享的?
    一个应用程序可以将自己的数据完全暴露,但外界看不到也不用看到。只需要有一套标准及统一的结构,来获取该应用里的数据和资源,例如:添加(insert)、删除(delete)、查询(query)、修改(update),当然要获得相应的权限。
  2. 如何将应用的数据暴露出去?
    Android 提供了 ContentProvider,一个程序可以通过实现一个 Content Provider 的抽象接口将自己的数据完全暴露出来,以类似数据库中表的方式。ContentProvider 存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方式。方式:创建一个属于自己的 Content provider、或者将自己的数据添加到一个已经存在的 Content provider中(前提是在具有相同的数据类型,并且有写入Content provider 的权限)
  3. 如何通过一套标准及统一接口获取到应用暴露的数据?
    Android 提供了 ContentResolver,外界的应用可以通过 ContentResolver接口访问 ContentProvider提供的数据。
    ContentResolver 通过 Uri来查询 ContentProvider 中提供的数据。 Uri在 这里 有做介绍。我们需要知道获取的数据段的名称、以及此数据段的数据类型。

3 在Manifecst中注册ContentResolver

使用ContentProvider来共享数据时,必须在AndroidManifest.xml文件中进行注册,类似于这样

<provider
         android:authorities="list"
         android:enabled=["true" | "false"]
         android:exported=["true" | "false"]
         android:grantUriPermissions=["true" | "false"]
         android:icon="drawable resource"
         android:initOrder="integer"
         android:label="string resource"
         android:multiprocess=["true" | "false"]
         android:name="string"
         android:permission="string"
         android:process="string"
         android:readPermission="string"
         android:syncable=["true" | "false"]
         android:writePermission="string">
   . . .
</provider>

Android系统通过 content:URI 的授权部分来识别内容提示器。
例如,假设下列的 Uri 要传递给 ContentResolve.query() 方法:

  • content://com.example.project.healthcareprovider/nurses/rn
  • content:表示数据是属于内容提供器
    授权(com.example.project.healthcareprovider):标识这一个具体的提供器。因此授权必须是唯一的。通常授权是一个完整的 ContentProvider 子类的名称。Uri 的路径部分被内容提供器用来标识集体的数据子集,但那些路径没有声明在清单文件中。

脚本详细内容这里不做介绍

4 ContentResolver 的接口

与数据库的操作基本一样

  • 【添加】
    返回值:final Uri
    函数声明:insert(Uri url, ContentValues values)
  • 【删除】
    返回值:final int
    函数声明:insert(Uri url, ContentValues values)
  • 【查询】
    Query the given URI, returning a Cursor over the result set
    返回值:final Cursor
    函数声明:query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  • 【修改】
    返回值:final int
    函数声明:update(Uri uri, ContentValues values, String where, String[] selectionArgs)

4 Cursor

ContentResolver 的查询操作,返回的为 Cursor。
Cursor 默认是行的集合。查询出来的cursor的初始位置是指向第一条记录的前一个位置的

  • cursor.moveToFirst() 指向查询结果的第一个位置。
    一般通过判断cursor.moveToFirst()的值为true或false来确定查询结果是否为空。
  • cursor.moveToNext() 用来做循环的,一般这样来用:while(cursor.moveToNext()){ }
  • cursor.moveToPrevious() 指向当前记录的上一个记录,是和moveToNext相对应的;
  • cursor.moveToLast() 指向查询结果的最后一条记录

下面代表的是一个cursor对象。
在这里插入图片描述
当我们是用 query 方法查询到的指向的是 cursor对象第一行的前一行,在该图中就是空行。然后使用 cursor.move.ToNext() 方法,指向了 cursor的第一行数据。每行中存在很多列数据,且数据类型不一定相同。

  • getColumnIndex(String columnName) 获取该列数据的index(索引)。返回值为int。
  • cursor.getxxx(int columnIdx) 获取 cursor 某一行 columnIdx列的数据内容,类型为xxx。比如cursor.getString() 获取该行数据中类型为string的数据。

例:

// get photo from Uri
public static String get_path_from_URI(Context context) {
   String result;
   Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
   if (cursor != null) {
       cursor.moveToFirst();
       int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
       result = cursor.getString(idx);
       cursor.close();
   } else {
       result = null;
   }
   return result;
}

使用cursor可以很方便的处理查询结果以便得到想要的数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值