`
ipjmc
  • 浏览: 708076 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

存储文件的ContentProvider

阅读更多
       基于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
0
分享到:
评论

相关推荐

    android 用ContentProvider操作文件

    在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享数据,而无需直接访问对方的内部存储。在本教程中,我们将深入探讨如何利用ContentProvider来操作文件,以及其在跨应用数据传输中的作用。 ...

    Android高级应用源码-利用contentprovider扫描内存卡上所有的音频文件

    通过ContentProvider,我们可以高效地实现对设备存储中音乐文件的检索,而无需直接访问文件系统,这样既符合Android的沙盒安全机制,又能提高应用程序的兼容性和可维护性。 首先,理解ContentProvider的基本工作...

    利用contentprovider扫描内存卡上所有的音频文件,扫描速度一般是300首歌需要50毫秒以内.zip

    本源码示例探讨了如何高效地利用ContentProvider扫描内存卡上的所有音频文件,尤其强调了快速扫描能力,声称能在50毫秒内处理大约300首歌曲。这个性能优化对于音乐播放器或其他需要快速访问媒体库的应用程序至关重要...

    ContentProvider

    6. **数据的序列化与反序列化**:ContentProvider在处理数据时,可能涉及到数据的序列化(比如JSON格式),以便更方便地在网络或存储中传输。 总之,ContentProvider是Android系统中非常重要的组成部分,它允许...

    ContentProvider共享数据的使用

    ContentProvider封装了数据存储的方式,使得不同的应用可以透明地读写数据,而无需关心数据具体是如何存储的,例如SQLite数据库、文件系统或者网络。本教程将深入探讨如何使用ContentProvider来实现数据共享。 ### ...

    contentprovider

    3. **提供数据模型**:ContentProvider需要管理的数据通常存储在SQLite数据库、文件系统或网络中。你需要创建一个适配器类来处理这些数据,例如SQLiteOpenHelper用于数据库操作。 4. **注册ContentProvider**:在...

    09_四大应用组件之ContentProvider.zip

    它封装了对数据库、文件等数据源的操作,使得其他应用可以通过标准的ContentResolver接口来读写这些数据,而无需直接访问数据存储的具体实现。这种方式提高了数据的安全性和一致性。 ContentProvider的结构主要包括...

    用SharePreferences做ContentProvider

    `SharedPreferences` 和 `ContentProvider` 是两种常见的数据存储和共享机制。本篇文章将深入探讨如何利用 `SharedPreferences` 作为数据存储,并通过实现 `ContentProvider` 来实现不同应用间的数据共享。 `...

    Android四种存储方式 sharedpreference,file,SQlite,contentprovider

    Android提供了四种主要的数据存储方式:SharedPreferences、文件存储、SQLite数据库和ContentProvider。以下是对这四种存储方式的详细介绍,以及如何在Android中实现数据库和表的创建、增删改查操作。 1. **...

    ContentProvider的使用Demo

    在Android系统中,ContentProvider是一种核心...实际开发中,ContentProvider可以用于复杂的数据共享场景,如分享多媒体文件、联系人信息等。通过熟练掌握ContentProvider,开发者可以构建更健壮、可扩展的应用程序。

    android contentprovider使用示例

    ContentProvider是Android系统提供的一种数据存储和访问机制,它允许应用程序之间进行数据交换,而无需暴露底层数据库或文件系统。通过ContentProvider,应用的数据可以被其他应用查询、插入、更新和删除。 2. **...

    ContentProvider项目

    通过实现ContentProvider,开发者可以将自己的数据存储方式(如SQLite数据库、文件系统或网络)封装起来,对外提供统一的访问接口。其他应用可以通过ContentResolver与ContentProvider交互,进行增删查改操作。 二...

    ContentProvider(其它程序共享访问).zip

    ContentProvider作为一个数据中间层,使得不同应用之间的数据交换变得可能,即使这些数据存储在私有的SQLite数据库、文件系统或其他存储方式中。让我们深入探讨ContentProvider的工作原理及其重要性。 首先,...

    SQLiteOpenHelper和ContentProvider区别

    在给定的文件名称列表中,“InvokeContentProvider”和“RegionContentProvider”很可能是两个自定义的ContentProvider实例,用于处理特定的数据操作和逻辑。开发者通常会根据实际需求,继承ContentProvider类并重写...

    Android ContentProvider全面解析

    通过ContentResolver,任何应用都可以查询、插入、更新或删除ContentProvider中存储的数据。ContentProvider的结构包括URI、MIME类型和Cursor,这些元素共同构成了数据操作的基础。 二、ContentProvider的主要功能 ...

    ContentProvider源码

    它允许应用程序之间通过URI(统一资源标识符)来访问和操作数据,这些数据可以存储在SQLite数据库、文件系统或网络中。ContentProvider的主要任务包括解析URI、执行数据操作(如增删改查)以及返回数据。 在Android...

    ContentProvider 共享SharedPreferences 值

    为了共享`SharedPreferences`,我们需要在`ContentProvider`中管理这些文件的读取和写入。 例如,我们可以创建一个名为`SharedPrefsProvider`的类,并在`onCreate()`方法中初始化`SharedPreferences`对象。对于两个...

    实验8 contentProvider共享数据1

    `ContentProvider`是Android四大组件之一,它封装了对数据的操作,使得其他应用可以通过标准的接口访问这些数据,而无需关心数据存储的具体形式,如SQLite数据库、文件系统或网络等。`ContentProvider`的核心在于...

Global site tag (gtag.js) - Google Analytics