Browse Source

- thumbnails on browsing local files during upload

tobiasKaminsky 10 years ago
parent
commit
d05d7361ff

+ 110 - 0
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java

@@ -156,6 +156,24 @@ public class ThumbnailsCacheManager {
         return true;
     }
     
+    public static boolean cancelPotentialWork(File file, ImageView imageView) {
+        final ThumbnailLocalGenerationTask bitmapWorkerTask = getBitmapLocalWorkerTask(imageView);
+
+        if (bitmapWorkerTask != null) {
+            final File bitmapData = bitmapWorkerTask.mFile;
+            // If bitmapData is not yet set or it differs from the new data
+            if (bitmapData == null || bitmapData != file) {
+                // Cancel previous task
+                bitmapWorkerTask.cancel(true);
+            } else {
+                // The same work is already in progress
+                return false;
+            }
+        }
+        // No task associated with the ImageView, or an existing task was cancelled
+        return true;
+    }
+    
     public static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {
         if (imageView != null) {
             final Drawable drawable = imageView.getDrawable();
@@ -166,6 +184,84 @@ public class ThumbnailsCacheManager {
          }
          return null;
      }
+    
+    public static ThumbnailLocalGenerationTask getBitmapLocalWorkerTask(ImageView imageView) {
+        if (imageView != null) {
+            final Drawable drawable = imageView.getDrawable();
+            if (drawable instanceof AsyncDrawable) {
+                final AsyncLocalDrawable asyncDrawable = (AsyncLocalDrawable) drawable;
+                return asyncDrawable.getBitmapWorkerTask();
+            }
+         }
+         return null;
+     }
+    
+    public static class ThumbnailLocalGenerationTask extends AsyncTask<File, Void, Bitmap> {
+        private final WeakReference<ImageView> mImageViewReference;
+        private File mFile;
+        
+        public ThumbnailLocalGenerationTask(ImageView imageView) {
+         // Use a WeakReference to ensure the ImageView can be garbage collected
+            mImageViewReference = new WeakReference<ImageView>(imageView);
+        }
+
+        // Decode image in background.
+        @Override
+        protected Bitmap doInBackground(File... params) {
+            Bitmap thumbnail = null;
+            
+            try {
+                mFile = params[0];
+                final String imageKey = String.valueOf(mFile.hashCode());
+    
+                // Check disk cache in background thread
+                thumbnail = getBitmapFromDiskCache(imageKey);
+    
+                // Not found in disk cache
+                if (thumbnail == null) { 
+                    // Converts dp to pixel
+                    Resources r = MainApp.getAppContext().getResources();
+                    
+                    int px = (int) Math.round(r.getDimension(R.dimen.file_icon_size));
+                    
+                    Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+                            mFile.getAbsolutePath(), px, px);
+                    
+                    if (bitmap != null) {
+                        thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+
+                        // Add thumbnail to cache
+                        addBitmapToCache(imageKey, thumbnail);
+                    }
+                }
+                
+            } catch (Throwable t) {
+                // the app should never break due to a problem with thumbnails
+                Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
+                if (t instanceof OutOfMemoryError) {
+                    System.gc();
+                }
+            }
+            
+            return thumbnail;
+        }
+        
+        protected void onPostExecute(Bitmap bitmap){
+            if (isCancelled()) {
+                bitmap = null;
+            }
+
+            if (mImageViewReference != null && bitmap != null) {
+                final ImageView imageView = mImageViewReference.get();
+                final ThumbnailLocalGenerationTask bitmapWorkerTask = getBitmapLocalWorkerTask(imageView);
+                if (this == bitmapWorkerTask && imageView != null) {
+                    if (imageView.getTag().equals(mFile.hashCode())) {
+                        imageView.setImageBitmap(bitmap);
+                    }
+                }
+            }
+        }
+    }
 
     public static class ThumbnailGenerationTask extends AsyncTask<OCFile, Void, Bitmap> {
         private final WeakReference<ImageView> mImageViewReference;
@@ -303,6 +399,20 @@ public class ThumbnailsCacheManager {
             return bitmapWorkerTaskReference.get();
         }
     }
+    
+    public static class AsyncLocalDrawable extends BitmapDrawable {
+        private final WeakReference<ThumbnailLocalGenerationTask> bitmapWorkerTaskReference;
+
+        public AsyncLocalDrawable(Resources res, Bitmap bitmap, ThumbnailLocalGenerationTask bitmapWorkerTask) {
+            super(res, bitmap);
+            bitmapWorkerTaskReference =
+                new WeakReference<ThumbnailLocalGenerationTask>(bitmapWorkerTask);
+        }
+
+        public ThumbnailLocalGenerationTask getBitmapWorkerTask() {
+            return bitmapWorkerTaskReference.get();
+        }
+    }
 
     
     /**

+ 1 - 4
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

@@ -47,7 +47,6 @@ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileStorageUtils;
@@ -234,9 +233,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                         }
                     }
                 } else {
-                    fileIcon.setImageResource(
-                            DisplayUtils.getResourceId(file.getMimetype(), file.getFileName())
-                    );
+                    fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));
                 }
 
                 if (checkIfFileIsSharedWithMe(file)) {

+ 47 - 1
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java

@@ -22,9 +22,12 @@ import java.util.Arrays;
 import java.util.Comparator;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.Uri;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.webkit.MimeTypeMap;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
@@ -32,6 +35,8 @@ import android.widget.ListView;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncLocalDrawable;
 import com.owncloud.android.utils.DisplayUtils;
 
 /**
@@ -46,7 +51,7 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
     private Context mContext;
     private File mDirectory;
     private File[] mFiles = null;
-
+    
     public LocalFileListAdapter(File directory, Context context) {
         mContext = context;
         swapDirectory(directory);
@@ -105,6 +110,7 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
             } else {
                 fileIcon.setImageResource(R.drawable.ic_menu_archive);
             }
+            fileIcon.setTag(file.hashCode());
 
             TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
             TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
@@ -125,6 +131,38 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
                     }
                     checkBoxV.setVisibility(View.VISIBLE);
                 }
+                
+             // get Thumbnail if file is image
+                if (isImage(file)){
+                // Thumbnail in Cache?
+                    Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                            String.valueOf(file.hashCode())
+                    );
+                    if (thumbnail != null){
+                        fileIcon.setImageBitmap(thumbnail);
+                    } else {
+                        // generate new Thumbnail
+                        if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
+                            final ThumbnailsCacheManager.ThumbnailLocalGenerationTask task = 
+                                    new ThumbnailsCacheManager.ThumbnailLocalGenerationTask(fileIcon);
+                            if (thumbnail == null) {
+                                thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                            }
+                            final AsyncLocalDrawable asyncDrawable = new AsyncLocalDrawable(
+                                    mContext.getResources(), 
+                                    thumbnail, 
+                                    task
+                            );
+                            fileIcon.setImageDrawable(asyncDrawable);
+                            task.execute(file);
+                        }
+                    }
+                } else {
+                    Uri selectedUri = Uri.fromFile(file);
+                    String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
+                    String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
+                    fileIcon.setImageResource(DisplayUtils.getResourceId(mimeType, file.getName()));
+                }  
 
             } else {
                 fileSizeV.setVisibility(View.GONE);
@@ -184,4 +222,12 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
         }
         notifyDataSetChanged();
     }
+    
+    private boolean isImage(File file) {
+        Uri selectedUri = Uri.fromFile(file);
+        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
+        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
+        
+        return (mimeType != null && mimeType.startsWith("image/"));
+   }
 }