Content provider作为信息的读出,比较常见的还有文件的读写,最基础的就是二进制文件的的读写,例如img文件,音频文件的读写。在数据库中存放了该文件的路径,我们可以通过ContentProvider获得InputSream和OutputStream,实现对文件的操作。Pro Android 4.0提及有关内容,但语焉不详,可同时参考http://www.grokkingandroid.com/handling-binary-data-with-contentproviders/,也可同时参考阅读的源代码,通过eclipse下载源代码,具体是sdk\sources\android-17\android\content\ContentProvider.java。

本笔记仍以BookProvider为例。

在数据库中存放文件路径

从ContentProvider的源代码注释中可知:Android会自动从uri的一个名为_data的列中获取文件路径。也就是Android在数据库表格中预留了列名_data,专门用于存放文件路径。和_id不同,_data不属于处理SQLite数据库表格BaseColumns类,也就是系统不会预留_data列,需要我们进行人工处理。

处理包括在provider描述中,为该表格增加_data的列:

  1. public class BookProviderMetaData {
  2. ......
  3. //由于我们要更新数据库,所以数据库的版本需要提升
  4. public static final int DATABASE_VERSION = 3;
  5. public static final class BookTableMetaData implements BaseColumns{
  6. ......
  7. public static final String FILE_NAME = "_data";
  8. }
  9. }

处理还包括在BookProvider中projectMap的映射关系:

  1. sBooksProjectionMap.put(BookTableMetaData.FILE_NAME, BookTableMetaData.FILE_NAME);

还有所涉及的增改查等内容。如果文件位于外接SD卡,还需要在AndriodManifest.xml中声明对SD卡具备读写权限。

重写openFile()方法

在源代码中,openFile()如下:

  1. public ParcelFileDescriptor openFile(Uri uri, String mode)
  2. throws FileNotFoundException {
  3. throw new FileNotFoundException("No files supported by provider at "
  4. + uri);
  5. }

即永远会抛出一个异常:FileNotFoundException,必须对之重写。

  1. @Override
  2. public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
  3. if(sUriMatch.match(uri) != BOOK_ITEM_URI_INDICATION)
  4. throw new IllegalArgumentException ("URI invalid. Use an id-based URI only.");
  5. /* 在代码或者reference,清晰写明:Convenience for subclasses that wish to implement openFile(Uri, String) by looking up
  6. * a column named "_data" at the given URI.
  7. * 简单地,在进行了uri的合法判断后,只需返回openFileHelper就可以。*/
  8. return openFileHelper(uri, mode);
  9. }

如何通过Content Provider进行文件读写

对于某个已的item的uri,获取二进制文件读写非常方便,如下所示

  1. try{
  2. OutputStream file = getContentResolver().openOutputStream(uri);
  3. ... ... //写处理
  4. file.close();
  5. }catch (Exception e){
  6. Log.e(“pro”,e.toString());
  7. }
  8. try{
  9. InputStream in = getContentResolver().openInputStream(uri);
  10. ... ... //读处理
  11. in.close();
  12. }catch (Exception e){
  13. Log.e(“pro”,e.toString());
  14. }

相关链接: 我的Android开发相关文章

转自http://blog.csdn.net/flowingflying/article/details/9244521

【转】Pro Android学习笔记(九):了解Content Provider(下下)的更多相关文章

  1. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  2. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...

  3. 【转】 Pro Android学习笔记(二二):用户界面和控制(10):自定义Adapter

    目录(?)[-] 设计Adapter的布局 代码部分 Activity的代码 MyAdapter的代码数据源和构造函数 MyAdapter的代码实现自定义的adapter MyAdapter的代码继续 ...

  4. 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode

    目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...

  5. 【转】 Pro Android学习笔记(五六):配置变化

    目录(?)[-] Activity的destorycreate过程 Fragment的destorycreate过程 onSaveInstanceState saveFragmentInstanceS ...

  6. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

  7. 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout

    目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...

  8. Pro Android学习笔记 ActionBar(1):Home图标区

     Pro Android学习笔记(四八):ActionBar(1):Home图标区 2013年03月10日 ⁄ 综合 ⁄ 共 3256字 ⁄ 字号 小 中 大 ⁄ 评论关闭 ActionBar在A ...

  9. 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...

  10. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

随机推荐

  1. erlang中遍历取出某个位置的最大值

    例:有这么一个列表,A = [["abc","bds",3],["ssdss","dddx",2],["sfa ...

  2. Svn服务器备份迁移小结

    注:svn备份千万不要采用打包压缩,然后解压文件的方式. 备份和还原之前先要关掉svn服务器. svn备份一般采用三种方式: 1)svnadmin dump 2)svnadmin hotcopy 3) ...

  3. Flask,ORM及模板引擎Jinja2

    跨域:http://blog.csdn.net/yannanxiu/article/details/53036508 下载flask_cors包 pip install flask-cors 使用fl ...

  4. android菜鸟学习笔记1----环境搭建

    Step1 JDK安装及配置: 1.下载并安装JDK: 根据自己系统情况,选择安装相应的JDK版本 当前系统:64位WIN8,内存8G 选择了Java SE 8u45 即JDK 1.8.0_45,可以 ...

  5. TCP/IP协议之ARP寻址

    ARP协议: 前面讲了网络层的寻址是通过IP地址来做的.其实一个数据包寻址包含两个部分:1 IP寻址.2 ARP寻址. ARP寻址是用在数据链路层上的.我们上网的电脑都有网卡.那么在数据链路层的进行传 ...

  6. Scipy.sparse矩阵的存储,读取和转化为稠密矩阵

    import numpy as np import scipy.sparse as sp m = sp.lil_matrix((7329,7329)) np.save(path,m) #用numpy的 ...

  7. Java for LeetCode 095 Unique Binary Search Trees II

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  8. 关于JMS和MQ

    2.1 什么是JMS? JMS是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输. 2.2 什么是消息模型 ○ Point-to-Point(P2P) --- 点对点 ○ P ...

  9. ssh_jar包选择

    1.struts2.3.29 + spring-framework-3.2.9.RELEASE +hibernate-distribution-3.6.10 * struts 所需jar 在:如下所示 ...

  10. 创建Django博客的数据库模型

    声明:此Django分类下的教程是追梦人物所有,地址http://www.jianshu.com/u/f0c09f959299,本人写在此只是为了巩固复习使用 blog最主要的功能就是展示我们写的文章 ...