Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Caching Bitmaps in a ContentProvider?

Tags:

android

How do you comprehend this note

Note: A ContentProvider might be a more appropriate place to store cached images if they are accessed more frequently, for example in an image gallery application.

in this training article https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html? Since I can't get Bitmap or File from Cursor, how can I cache Bitmaps via ContentProvider?

like image 544
zhang xuefeng Avatar asked Nov 08 '12 10:11

zhang xuefeng


2 Answers

You actually can read and write Files using a ContentProvider.

To support this in your own ContentProvider you'll have to include your supported File MIME types in the getStreamTypes() method. Check the MIME types section of the Android ContentProvider tutorial here for more info.

You will also need to implement the openFile(Uri uri, String mode) method which is where you'll actually choose the File directory and name based on the Uri provided to the ContentResolver. Here's a sample implementation of that method:

  @Override
  public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
      File root = getContext().getFilesDir();
      File path = new File(root, uri.getEncodedPath());
      path.mkdirs();
      File file = new File(path, "file_"+uri.getLastPathSegment());

      int imode = 0;
      if (mode.contains("w")) {
        imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
        if (!file.exists()) {
          try {
            file.createNewFile();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
      if (mode.contains("r"))
        imode |= ParcelFileDescriptor.MODE_READ_ONLY;
      if (mode.contains("+"))
        imode |= ParcelFileDescriptor.MODE_APPEND;

      return ParcelFileDescriptor.open(file, imode);
  }

You can use whatever logic you'd like here to choose your File directory. This code just uses the applications files directory, but for the purposes of Bitmap caching this should probably use a temp cache directory.

Finally, your code to access the ContentProvider file data should look something like this:

ContentResolver cr = getContext().getContentResolver();
InputStream inputStream = cr.openInputStream(uri);

Alternatively you'd use ContentResolver.openOutputStream(uri) to write your file data to the ContentProvider.

The Bitmap caching tutorial would require a fair bit of modifications to use a ContentProvider as the Disk cache, but I do believe this is what that note was referring to.

like image 113
cephus Avatar answered Oct 28 '22 14:10

cephus


I highly recommend using the https://github.com/nostra13/Android-Universal-Image-Loader library for downloading and caching images

You can download the library as a JAR-file that is easily included into any Android project

Features from the official page:

->Multithread image loading

->Possibility of wide tuning ImageLoader's configuration (thread pool size, HTTP options, memory and disc cache, display image options, and others)

->Possibility of image caching in memory and/or on device's file sysytem (or SD card)

->Possibility to "listen" loading process

->Possibility to customize every display image call with separated options Widget support

like image 45
G M Ramesh Avatar answered Oct 28 '22 12:10

G M Ramesh