- thumbnails on browsing local files during upload

This commit is contained in:
tobiasKaminsky 2014-11-23 13:34:24 +01:00
parent b2158a8673
commit d05d7361ff
3 changed files with 158 additions and 5 deletions

View file

@ -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();
}
}
/**

View file

@ -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)) {

View file

@ -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/"));
}
}