Pro Android学习笔记(九):了解Content Provider(下下)

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的列:

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

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

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

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

重写openFile()方法

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

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

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

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

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

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

try{
	OutputStream file = getContentResolver().openOutputStream(uri);
	... ... //写处理
	file.close();
}catch (Exception e){
	Log.e(“pro”,e.toString());
}

try{
	InputStream in = getContentResolver().openInputStream(uri);
	... ... //读处理
	in.close();
}catch (Exception e){
	Log.e(“pro”,e.toString());
}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值