Provider的不常见访问方式

  • Batch access:访问ContentProvider的一中模式,使用该模式可以同时对provider进行多个操作,且支持同时操作多个表。使用时首先构建一个ContentProviderOperation序列,然后使用ContentResolver.applyBatch方法把这些操作分发到provdier中,调用applyBatch参数时需要传入provider的authority而不是某个表的Uri,这样就可以使得不同的operation查询不同的表。
  • 当你的应用A不具有访问某个provider的权限时,你可以通过Intent的方法来访问。典型的比如选择一个联系人,在A中可以发送一个Intent,设置相应的action和MIME类型,然后就会启动比如联系人应用来供用户选择一个联系人,带选择完后,应用A的onActivityResult中就会收到返回的Intent,通过getData方法得到其中的Uri,这个Uri就指向了用户选择的联系人,同时,在联系人应用通过对返回的intent设置了FLAG_GRANT_READ_URI_PERMISSION以及FLAG_GRANT_WRITE_URI_PERMISSION两个分别给接收该intent的Activity赋予临时读/写该Uri指向的数据的权限,该权限直到该Activity finish之后就失效。另外一中方法就是通过发送Intent,并把需要的额外数据放入Intent中,然后交由另外一个具有该权限的应用去完成你想对该provider的操作。

用户自定义MIME

  • 对于用户自定义的,也称作vendor-specific,的MIME类型,MIME类型的固定格式为type/subtype,对于自定的的MIME,其type固定为:对于多行:vnd.android.cursor.dir,对于单行为:vnd.android.cursor.item,而对于subtype类型则在遵守“vnd.<name>.<type>”形式的范围内由用户自定义。name必须全球唯一,一般为公司名或者报名,type则应该与URI类型有一对一的关系。例如对于一个authority为com.willhua.trains的provider,对应的表分别为list1和list2,那么对于uri,content://com.willhua.trains/list1,其对应的MIME类型可以设定为vnd.android.cursor.dir/vnd.willhua.list1,对于uri,content://com.willhua.trains/list2/5,其对应的MIME类型可以设定为vnd.android.cursor.dir/vnd.willhua.list2。

设计数据结构tips

  • 最好有一个名为_ID的int列来作为primary key,这样的话即可以把它当做foreign key来映射其他表中的数据,而且如果要把provider的查询结果链入listview的,那么就必须有_ID列(BaseColumns._ID;
  • 使用BOLB(binary large object)类型来存储数据体积变化大或者数据结构不同的数据,比如protocol buffer或者JSON数据
  • 同样可以使用BLOB来做一个schema-independent的表。一般来说,定一个int的primarykey,一个表示MIME类型的列,一个或者多个BLOB列,BLOB中的数据则可以根据MIME类型来解释,这样的话就实现了把不同shchema类型的数据存储在了同一个表中,ConatactsContract.Data就是这样一个例子的表。

URI

  • content Uri分成几个部分,首先是开始的schema部分,即content://,这个都是一样的;然后是provider的authority,ContentRsolver就是根据Uri这个部分匹配系统中已知的provider表而确定(resolver)需要使用哪个provider,从而调用相应provider的对于查询方法;然后就是路径或者表;最后就是若是表示单行的Uri则加上行ID。
  • 需要注意的是,路径或者表部分没有限定说只能有一个片段或者层级,比如content://com.willhua.blog/tablea/dataa/8或者content://com.willhua.blog/tablea/datab,这样的Uri也是可以的,其中tablea/dataa和tablea/datab即表示路径部分,且表示的表分别为dataa和datab,这样的做法可以更好的显示表的层级关系。
  • 在使用UriMatcher使用通配符判断Uri类型时,符号‘*’表示任意长度的有效字符,‘#’表示任意长度的数字字符

ContentProvider的实现

  • query():对于查询结果没有任何匹配的项的时候应该返回getCount==0的cursor,而不是null。只有当查询过程中发生错误才返回null。如果provider使用的数据存储不是SQLite,那么可以使用cursor的一些子类,比如MatrixCursor作为返回值。
  • insert():返回的值记得以该表的Uri然后append新插入行的ID.
  • delete():有时候可以考虑使用一个比如delete列来表示该行是否被删除来代替真正的从表中删除
  • update()
  • onCreate():应该尽可能的降低此函数的执行时间以提高响应速度。如果是使用SQLite作为数据存储,那么最好使用SQLiteOpenHelper,它将把创建SQL表的时候延迟到第一次打开database的时候。当第一次调用getWritableDatabase的时候,将调用Helper的onCreate函数。
  • getType():用于返回一个MIME格式的的字符串来描述根据content URI参数返回的数据类型。
  • getStreamTypes():如果provider提供files,那么应该实现此函数。用于返回与content URI对应的MIME类型序列。例如某provider提供.jpg, .png两种图片,如果另一个应用调用getStreamTypes传入的filter参数为“image/*”,那么getStreamTypes应该返回{“image/jpg”, "image/png"}。如果没有任何匹配该filter的,那么返回null。

Provider权限控制

  • 对于放置在内部存储器(internal)上的数据,默认是只能由本应用访问的。但是如果把这些数据作为一个provider的仓库的话,且在没有对provider做额外的权限控制的条件下,那么别的应用程序就可以通过provider完全访问这些数据,也就是相当于把一个私有的数据完全开放了。这并不合理。所以,我们应该根据需要对provider进行一些访问权限控制。
  • 对provider的权限设置可以分为三个级别:整个provider的完全权限,使用provider的android:permission控制,这个权限表示对整个provider的完全读写权限;单独的读或者写权限,使用provider的android:readPermission和android:writePermission分别控制对整个provider的读写权限控制;路径级别的权限控制,使用provider的子元素<path-permission>控制,可以控制针对某个具体的URI的读写,读,写或者三者的权限;
  • 这三个权限的优先级逐级增大,即假如某个数据同时被设定了整个provider的权限和path级别的权限,那么外部应用就得必须有path级别的权限才能访问这个数据。
  • 临时权限,使用provider的android:grantUriPermission属性(默认false)和子元素<grant-uri-permission>来分别控制对整个provider或者某个特定uri的临时权限。具有临时权限的访问忽视前面说的三级权限要求。可以通过Content.revokeUriPermission()来收回针对某个uri的临时权限。在Intent通过FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION来给别的应用分别赋予临时读写权限。
  • 如果provider没有指明所需的权限,那么别的应用就无法访问到这个provider。但是在provider所在应用中的其他组件是一直都是忽视所需权限要求的,有对该provider完整的读写权限。

Android细笔记--ContentProvider的更多相关文章

  1. Android细笔记--DataStorage

    Shared Preferences 即使应用被杀了,shared preference也还是存在的 Internal Storage 创建于internal的文件只对本应用开放权限,即使手机用户本身 ...

  2. android学习笔记54——ContentProvider

    ContentProvider ContentProvider用于实现数据共享. ContentProvider是不同应用程序之间进行数据交换的标准API,其以某种Uri的形式对外提供数据,允许其他应 ...

  3. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  4. 【转】Android开发笔记(序)写在前面的目录

    原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...

  5. udacity android 实践笔记: lesson 4 part b

    udacity android 实践笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  6. 【转】Pro Android学习笔记(七):了解Content Provider(下上)

    我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...

  7. Android四大组件--ContentProvider详解(转)

    一.相关ContentProvider概念解析: 1.ContentProvider简介在Android官方指出的Android的数据存储方式总共有五种,分别是:Shared Preferences. ...

  8. android 应用笔记

    android 应用笔记 android 应用笔记 小书匠 Android 综合教程 Android常用技巧 安卓系统架构 安卓源码开发 安卓驱动 Linux内核 安卓应用开发 Java 教程 tic ...

  9. Android 学习笔记之Volley(七)实现Json数据加载和解析...

    学习内容: 1.使用Volley实现异步加载Json数据...   Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...

随机推荐

  1. @font-face使用

    转自http://www.tuicool.com/articles/QVf6nei 一.webfont与@font-face 什么是webfont web font,又称之为 在线字体 或者 网络字体 ...

  2. angularjs 请求后端接口请求了两次

    用angularjs的过程中发现,每次打开页面,请求后端的接口都请求了两次 如下图可以看到, http://192.168.1.109:8080/zdh/api/v1/goods/54 这个页面loa ...

  3. 缓存Cookie、session、localStorage的区别

    cookie Cookie就是服务器暂存放在你计算机上的一笔资料,好让服务器用来辨认你的计算机.当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文 ...

  4. iOS开发使用半透明模糊效果方法整理

    虽然iOS很早就支持使用模糊效果对图片等进行处理,但尤其在iOS7以后,半透明模糊效果得到大范围广泛使用.包括今年最新发布的iOS8也沿袭了这一设计,甚至在OS X 10.10版Yosemite中也开 ...

  5. opendaylight的Beryllium安装

    1.首先安装jdk  #sudo apt-get install openjdk-7-jdk 2.安装vim编辑工具   #sudo apt-get install vim 3.编辑~/.bashrc ...

  6. C#读取数据库中的表

    private int ExistOrNot(string name)    //判断当前数据表是否存在 { con = new SqlConnection(s); DataSet ds = new ...

  7. 关于Javascript作用域及作用域链的总结

    本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...

  8. OpenCV2:Mat

    1.Mat基础 在计算机内存中,数字图像是已矩阵的形式保存的.OpenCV2中,数据结构Mat是保存图像像素信息的矩阵,它主要包含两部分:矩阵头和一个指向像素数据的矩阵指针. 矩阵头主要包含,矩阵尺寸 ...

  9. MongoDB初学

    参考:MongoDB 教程 | 菜鸟教程 安装 1.下载安装,从官网下载winows安装包,安装到d盘(注意路径) 2.由于我安装在d盘,所以在d盘创建文件夹data,里面创建db文件夹 3.启动方法 ...

  10. 工作流引擎Oozie(二):coordinator

    1. 简介 coordinator是workflow的定时提交器,基于时间条件与数据生成触发(based on time and data triggers).简单点说,coordinator按所定义 ...