Home | History | Annotate | Download | only in data
      1 package com.bumptech.glide.load.data;
      2 
      3 import android.content.ContentResolver;
      4 import android.content.Context;
      5 import android.net.Uri;
      6 import android.util.Log;
      7 
      8 import com.bumptech.glide.Priority;
      9 
     10 import java.io.FileNotFoundException;
     11 import java.io.IOException;
     12 
     13 /**
     14  * A DataFetcher that uses an {@link android.content.ContentResolver} to load data from a {@link android.net.Uri}
     15  * pointing to a local resource.
     16  *
     17  * @param <T> The type of data that will obtained for the given uri (For example, {@link java.io.InputStream} or
     18  * {@link android.os.ParcelFileDescriptor}.
     19  */
     20 public abstract class LocalUriFetcher<T> implements DataFetcher<T> {
     21     private static final String TAG = "LocalUriFetcher";
     22     private final Uri uri;
     23     private final Context context;
     24     private T data;
     25 
     26     /**
     27      * Opens an input stream for a uri pointing to a local asset. Only certain uris are supported
     28      *
     29      * @see ContentResolver#openInputStream(android.net.Uri)
     30      *
     31      * @param context A context (this will be weakly referenced and the load will fail if the weak reference
     32      *                is cleared before {@link #loadData(Priority)}} is called.
     33      * @param uri A Uri pointing to a local asset. This load will fail if the uri isn't openable by
     34      *            {@link ContentResolver#openInputStream(android.net.Uri)}
     35      */
     36     public LocalUriFetcher(Context context, Uri uri) {
     37         this.context = context.getApplicationContext();
     38         this.uri = uri;
     39     }
     40 
     41     @Override
     42     public final T loadData(Priority priority) throws Exception {
     43         ContentResolver contentResolver = context.getContentResolver();
     44         data = loadResource(uri, contentResolver);
     45         return data;
     46     }
     47 
     48     @Override
     49     public void cleanup() {
     50         if (data != null) {
     51             try {
     52                 close(data);
     53             } catch (IOException e) {
     54                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
     55                     Log.v(TAG, "failed to close data", e);
     56                 }
     57             }
     58 
     59         }
     60     }
     61 
     62     @Override
     63     public void cancel() {
     64         // Do nothing.
     65     }
     66 
     67     @Override
     68     public String getId() {
     69         return uri.toString();
     70     }
     71 
     72 
     73     /**
     74      * Returns a concrete data type from the given {@link android.net.Uri} using the given
     75      * {@link android.content.ContentResolver}.
     76      *
     77      * @throws FileNotFoundException
     78      */
     79     protected abstract T loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException;
     80 
     81     /**
     82      * Closes the concrete data type if necessary.
     83      *
     84      * <p>
     85      *     Note - We can't rely on the closeable interface because it was added after our min API level. See issue #157.
     86      * </p>
     87      *
     88      * @param data The data to close.
     89      * @throws IOException
     90      */
     91     protected abstract void close(T data) throws IOException;
     92 }
     93 
     94