存储文件的ContentProvider

标签: 文件 contentprovider | 发表时间:2012-03-08 23:37 | 作者:
出处:http://www.iteye.com
       基于SQLite的ContentProvider我们见得多了,但是我们在做Android应用时,有时候程序需要下载网络上的图片,这时候我们希望能够把图片缓存到客户端本地,下次再要显示该图片时就不用再从网络上下载了,直接从本地缓存读取,这就需要用到存储文件的ContentProvider 。
        这里只关注如何通过ContentProvider缓存图片,对Android本地文件操作不熟悉的同学可以参考 Android文件存储,其他内容就不介绍了。
        在Mainfest文件中,我们定义的ContentProvider名称为FileProvider,最后别忘了添加权限android.permission.WRITE_EXTERNAL_STORAGE
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ipjmc.demo.fileprovider"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" >
        <activity android:label="@string/app_name" android:name=".FileProviderActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <provider android:name=".FileProvider" android:authorities="com.ipjmc.demo.fileprovider" />
    </application>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

        FileContentProvider代码如下,其中openFile是必须实现的方法,已经对关键的代码给出了注释

package com.ipjmc.demo.fileprovider;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

public class FileProvider extends ContentProvider {

    /*
	* 为了简单起见,这里直接将asset/pic.png拷贝到了程序的ExternalFilesDir,实际中应该是从网络上下载图片到ExternalFilesDir。
	*/
	@Override
	public boolean onCreate() {
		File file = new File(getContext().getExternalFilesDir(null), "pic.png");
		if (!file.exists()) {
			AssetManager assetManager = getContext().getAssets();

			try {
				InputStream is = assetManager.open("pic.png");
				OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
				byte [] buf = new byte[1024];
				int len = 0;
				while ((len = is.read(buf)) > 0) {
					os.write(buf, 0, len);
				}
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
		}
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getType(Uri uri) {
		if (uri.toString().endsWith(".png")) {
			return "image/png";
		}
		return null;
	}

	/*
	* 就是做一次映射,返回uri指定的文件的文件描述符
	*/
	@Override
	public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
		if ("image/png".equals(getType(uri))) {
			File file = new File(getContext().getExternalFilesDir(null), uri.getPath());
			if (file.exists()) {
				return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
			}
		}
		throw new FileNotFoundException(uri.getPath());
	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}
}

        下面是如何在Activity中该ContentProvider,其中Activity的布局文件我就不贴了,就一个ImageView
package com.ipjmc.demo.fileprovider;

import java.io.FileNotFoundException;
import java.io.InputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ImageView;

public class FileProviderActivity extends Activity {
	
	public static final Uri URI = Uri.parse("content://com.ipjmc.demo.fileprovider/pic.png");
	
	ImageView mImageView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mImageView = (ImageView) findViewById(R.id.image);

		try {
		    //通过ContentResolver获取图片的输入流,再转化为Bitmap
			InputStream is = getContentResolver().openInputStream(URI);
			Bitmap bitmap = BitmapFactory.decodeStream(is);
			mImageView.setImageBitmap(bitmap);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
    }
}
		


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [文件 contentprovider] 推荐:

存储文件的ContentProvider

- - ITeye博客
       基于SQLite的ContentProvider我们见得多了,但是我们在做Android应用时,有时候程序需要下载网络上的图片,这时候我们希望能够把图片缓存到客户端本地,下次再要显示该图片时就不用再从网络上下载了,直接从本地缓存读取,这就需要用到存储文件的ContentProvider.

Android入门:ContentProvider

- - ITeye博客
一、ContentProvider介绍. ContentProvider翻译为“内容提供者”;. 定义:指该应用包含一些方法,供外界访问,其他应用程序可以调用该方法,比如如果应用A创建了一个数据库“test.db”,默认是私有的,即其他应用程序不能对其进行操作,但是如果应用A使用了ContentProvider,则其他应用程序可以访问该数据库;.

Android ContentProvider总结

- - CSDN博客推荐文章
1) ContentProvider为存储和读取数据提供了统一的接口. 2) 使用ContentProvider,应用程序可以实现数据共享. 3) android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等). 1)ContentProvider简介.

android ContentProvider使用详解

- - CSDN博客移动开发推荐文章
由于之前主要做手机游戏相关的开发,所以ContentProvider了解的不多,今天就来学习一下. 首先来了解一下ContentProvider是什么. ContentProvider是Android的四大组件之一,可见它在Android中的作用非同小可. 它主要的作用是:实现各个应用程序之间的(跨应用)数据共享,比如联系人应用中就使用了ContentProvider,你在自己的应用中可以读取和修改联系人的数据,不过需要获得相应的权限.

python 下载文件

- Eric - python相关的python 教程和python 下载你可以在老王python里寻觅
之前给大家分享的python 多线程抓取网页,我觉的大家看了以后,应该会对python 抓取网页有个很好的认识,不过这个只能用python 来抓取到网页的源代码,如果你想用做python 下载文件的话,上面的可能就不适合你了,最近我在用python 做文件下载的时候就遇到这个问题了,不过最终得以解决,为了让大家以后碰过这个问题有更好的解决办法,我把代码发出来:.

Ext文件系统

- Haides - 博客园-首页原创精华区
  虽然从Ext2到Ext4,找数据的方式发生了变化,但是,磁盘的布局还是非常相似的. 其实这个东西也不需要变化,因为现在也没什么特别巧妙的方式,而且磁盘的吞吐量、效率的瓶颈也不在这里. 当然,这里排除那些根据自身文件特点设计的数据库,毕竟还是为了支持通用文件.   Boot在第一个块,放的应该是引导程序,超级块就放在了第二个块上,如果不是可以在mount的时候通过参数sb来设置.

Linux 文件结构

- Shiina Luce - OSMSG
想了解 Linux 文件系统树形结构,却又不愿翻阅 FHS 的朋友,可以参考 skill2die4 制作的这张简图. 此图算是 FHS 的图形化版本,简要的说明了 Linux 系统中各个目录的用途及层级关系,适合初学者使用参考. 不过其中较新的如 /run 目录并未在其中出现. 做为参考,这是 Fedora 16 Beta i686 上的文件结构:.

多文件上传

- - BlogJava-首页技术区
多文件上传 jquery的插件. 使用的方法  导入 jquery.js 及 jquery.MultiFile.js ,. 方式一: 后台是文件数组  .  private File[] upload; // 与jsp表单中的名称对应. 在 form 中加入 即可.

Zookeeper配置文件

- - 学着站在巨人的肩膀上
复制conf/zoo_sample.cfg文件为conf/zoo.cfg,修改其中的数据目录. tickTime:这个时间作为Zookeeper服务器之间或者服务器与客户端之间维护心跳的时间,时间单位毫秒. initLimit:选举leader的初始延时. 由于服务器启动加载数据需要一定的时间(尤其是配置数据非常多),因此在选举 Leader后立即同步数据前需要一定的时间来完成初始化.