现在的位置: 首页 > 综合 > 正文

ContentProvider 之文件储存

2013年05月04日 ⁄ 综合 ⁄ 共 6746字 ⁄ 字号 评论关闭

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

这里只关注如何通过ContentProvider缓存图片,对Android本地文件操作不熟悉的同学可以参考Android文件存储,其他内容就不介绍了。

在Mainfest文件中,我们定义的ContentProvider名称为FileProvider,最后别忘了添加权限android.permission.WRITE_EXTERNAL_STORAGE

Xml代码
复制代码

收藏代码
  1. <?xml
    version="1.0"
    encoding="utf-8"?>
  2. <manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.ipjmc.demo.fileprovider"
  4. android:versionCode="1"
  5. android:versionName="1.0"
    >
  6. <uses-sdk
    android:minSdkVersion="8"
    />
  7. <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    >
  8. <activity
    android:label="@string/app_name"
    android:name=".FileProviderActivity"
    >
  9. <intent-filter
    >
  10. <action
    android:name="android.intent.action.MAIN"
    />
  11. <category
    android:name="android.intent.category.LAUNCHER"
    />
  12. </intent-filter>
  13. </activity>
  14. <provider
    android:name=".FileProvider"
    android:authorities="com.ipjmc.demo.fileprovider"
    />
  15. </application>
  16. <uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    />
  17. </manifest>

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

Java代码
复制代码

收藏代码
  1. package com.ipjmc.demo.fileprovider;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import android.content.ContentProvider;
  10. import android.content.ContentValues;
  11. import android.content.res.AssetManager;
  12. import android.database.Cursor;
  13. import android.net.Uri;
  14. import android.os.ParcelFileDescriptor;
  15. public class FileProvider
    extends ContentProvider {
  16. /*
  17. * 为了简单起见,这里直接将asset/pic.png拷贝到了程序的ExternalFilesDir,实际中应该是从网络上下载图片到ExternalFilesDir。
  18. */
  19. @Override
  20. public boolean onCreate() {
  21. File file = new File(getContext().getExternalFilesDir(null),
    "pic.png");
  22. if (!file.exists()) {
  23. AssetManager assetManager = getContext().getAssets();
  24. try {
  25. InputStream is = assetManager.open("pic.png");
  26. OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
  27. byte [] buf = new
    byte[1024];
  28. int len = 0;
  29. while ((len = is.read(buf)) >
    0) {
  30. os.write(buf, 0, len);
  31. }
  32. is.close();
  33. os.close();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. @Override
  42. public Cursor query(Uri uri, String[] projection, String selection,
  43. String[] selectionArgs, String sortOrder) {
  44. // TODO Auto-generated method stub
  45. return null;
  46. }
  47. @Override
  48. public String getType(Uri uri) {
  49. if (uri.toString().endsWith(".png")) {
  50. return "image/png";
  51. }
  52. return null;
  53. }
  54. /*
  55. * 就是做一次映射,返回uri指定的文件的文件描述符
  56. */
  57. @Override
  58. public ParcelFileDescriptor openFile(Uri uri, String mode)
    throws FileNotFoundException {
  59. if ("image/png".equals(getType(uri))) {
  60. File file = new File(getContext().getExternalFilesDir(null), uri.getPath());
  61. if (file.exists()) {
  62. return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
  63. }
  64. }
  65. throw new FileNotFoundException(uri.getPath());
  66. }
  67. @Override
  68. public Uri insert(Uri uri, ContentValues values) {
  69. // TODO Auto-generated method stub
  70. return null;
  71. }
  72. @Override
  73. public int delete(Uri uri, String selection, String[] selectionArgs) {
  74. // TODO Auto-generated method stub
  75. return 0;
  76. }
  77. @Override
  78. public int update(Uri uri, ContentValues values, String selection,
  79. String[] selectionArgs) {
  80. // TODO Auto-generated method stub
  81. return 0;
  82. }
  83. }

下面是如何在Activity中该ContentProvider,其中Activity的布局文件我就不贴了,就一个ImageView

Java代码
复制代码

收藏代码
  1. package com.ipjmc.demo.fileprovider;
  2. import java.io.FileNotFoundException;
  3. import java.io.InputStream;
  4. import android.app.Activity;
  5. import android.graphics.Bitmap;
  6. import android.graphics.BitmapFactory;
  7. import android.net.Uri;
  8. import android.os.Bundle;
  9. import android.widget.ImageView;
  10. public class FileProviderActivity
    extends Activity {
  11. public static
    final Uri URI = Uri.parse("content://com.ipjmc.demo.fileprovider/pic.png");
  12. ImageView mImageView;
  13. /** Called when the activity is first created. */
  14. @Override
  15. public void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.main);
  18. mImageView = (ImageView) findViewById(R.id.image);
  19. try {
  20. //通过ContentResolver获取图片的输入流,再转化为Bitmap
  21. InputStream is = getContentResolver().openInputStream(URI);
  22. Bitmap bitmap = BitmapFactory.decodeStream(is);
  23. mImageView.setImageBitmap(bitmap);
  24. } catch (FileNotFoundException e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. }
  28. }
  29. }

抱歉!评论已关闭.