mirror of
https://github.com/nextcloud/android.git
synced 2024-10-22 20:16:02 +03:00
Added requested changes.
This commit is contained in:
parent
ba2d805197
commit
db4ccec8ee
6 changed files with 132 additions and 111 deletions
|
@ -5,6 +5,5 @@
|
|||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="lib" path="third_party/disklrucache-2.0.2.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
|
6
lint.xml
6
lint.xml
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
<issue id="NewApi">
|
||||
<ignore path="src/com/owncloud/android/ui/adapter/Utils.java" />
|
||||
</issue>
|
||||
</lint>
|
|
@ -22,17 +22,18 @@ import com.owncloud.android.utils.Log_OC;
|
|||
public class DiskLruImageCache {
|
||||
|
||||
private DiskLruCache mDiskCache;
|
||||
private CompressFormat mCompressFormat = CompressFormat.JPEG;
|
||||
private int mCompressQuality = 70;
|
||||
private static final int APP_VERSION = 1;
|
||||
private CompressFormat mCompressFormat;
|
||||
private int mCompressQuality;
|
||||
private static final int CACHE_VERSION = 1;
|
||||
private static final int VALUE_COUNT = 1;
|
||||
private static final int IO_BUFFER_SIZE = 8 * 1024;
|
||||
private static final String TAG = "DiskLruImageCache";
|
||||
|
||||
public DiskLruImageCache( Context context,String uniqueName, int diskCacheSize,
|
||||
CompressFormat compressFormat, int quality ) {
|
||||
try {
|
||||
final File diskCacheDir = getDiskCacheDir(context, uniqueName );
|
||||
mDiskCache = DiskLruCache.open( diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize );
|
||||
mDiskCache = DiskLruCache.open( diskCacheDir, CACHE_VERSION, VALUE_COUNT, diskCacheSize );
|
||||
mCompressFormat = compressFormat;
|
||||
mCompressQuality = quality;
|
||||
} catch (IOException e) {
|
||||
|
@ -44,7 +45,7 @@ public class DiskLruImageCache {
|
|||
throws IOException, FileNotFoundException {
|
||||
OutputStream out = null;
|
||||
try {
|
||||
out = new BufferedOutputStream( editor.newOutputStream( 0 ), Utils.IO_BUFFER_SIZE );
|
||||
out = new BufferedOutputStream( editor.newOutputStream( 0 ), IO_BUFFER_SIZE );
|
||||
return bitmap.compress( mCompressFormat, mCompressQuality, out );
|
||||
} finally {
|
||||
if ( out != null ) {
|
||||
|
@ -57,11 +58,7 @@ public class DiskLruImageCache {
|
|||
|
||||
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
|
||||
// otherwise use internal cache dir
|
||||
final String cachePath =
|
||||
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
|
||||
!Utils.isExternalStorageRemovable() ?
|
||||
Utils.getExternalCacheDir(context).getPath() :
|
||||
context.getCacheDir().getPath();
|
||||
final String cachePath = context.getExternalCacheDir().getPath();
|
||||
|
||||
Log_OC.d("DiskCache", "create dir: " + cachePath + File.separator + uniqueName);
|
||||
|
||||
|
@ -116,7 +113,7 @@ public class DiskLruImageCache {
|
|||
final InputStream in = snapshot.getInputStream( 0 );
|
||||
if ( in != null ) {
|
||||
final BufferedInputStream buffIn =
|
||||
new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
|
||||
new BufferedInputStream( in, IO_BUFFER_SIZE );
|
||||
bitmap = BitmapFactory.decodeStream( buffIn );
|
||||
}
|
||||
} catch ( IOException e ) {
|
||||
|
|
|
@ -19,6 +19,7 @@ package com.owncloud.android.ui.adapter;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Vector;
|
||||
|
||||
|
@ -30,6 +31,8 @@ import android.content.res.Resources;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.ThumbnailUtils;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.TypedValue;
|
||||
|
@ -69,6 +72,7 @@ import org.apache.http.util.EntityUtils;
|
|||
* instance.
|
||||
*
|
||||
* @author Bartek Przybylski
|
||||
* @Author Tobias Kaminsky
|
||||
*
|
||||
*/
|
||||
public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
||||
|
@ -81,18 +85,21 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
private FileDataStorageManager mStorageManager;
|
||||
private Account mAccount;
|
||||
private ComponentsGetter mTransferServiceGetter;
|
||||
private final Object mDiskCacheLock = new Object();
|
||||
private DiskLruImageCache mDiskLruCache;
|
||||
private boolean mDiskCacheStarting = true;
|
||||
private final Object thumbnailDiskCacheLock = new Object();
|
||||
private DiskLruImageCache mThumbnailCache;
|
||||
private boolean mThumbnailCacheStarting = true;
|
||||
private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
|
||||
private CompressFormat mCompressFormat = CompressFormat.JPEG;
|
||||
private int mCompressQuality = 70;
|
||||
private static final CompressFormat mCompressFormat = CompressFormat.JPEG;
|
||||
private static final int mCompressQuality = 70;
|
||||
private OwnCloudClient mClient;
|
||||
private Bitmap defaultImg;
|
||||
|
||||
public FileListListAdapter(Context context, ComponentsGetter transferServiceGetter) {
|
||||
mContext = context;
|
||||
mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);
|
||||
mTransferServiceGetter = transferServiceGetter;
|
||||
defaultImg = BitmapFactory.decodeResource(mContext.getResources(),
|
||||
DisplayUtils.getResourceId("image/png", "default.png"));
|
||||
|
||||
// Initialise disk cache on background thread
|
||||
new InitDiskCacheTask().execute();
|
||||
|
@ -101,8 +108,9 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
class InitDiskCacheTask extends AsyncTask<File, Void, Void> {
|
||||
@Override
|
||||
protected Void doInBackground(File... params) {
|
||||
synchronized (mDiskCacheLock) {
|
||||
mDiskLruCache = new DiskLruImageCache(mContext, "thumbnailCache", DISK_CACHE_SIZE, mCompressFormat,mCompressQuality);
|
||||
synchronized (thumbnailDiskCacheLock) {
|
||||
mThumbnailCache = new DiskLruImageCache(mContext, "thumbnailCache",
|
||||
DISK_CACHE_SIZE, mCompressFormat, mCompressQuality);
|
||||
|
||||
try {
|
||||
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
|
||||
|
@ -122,24 +130,42 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mDiskCacheStarting = false; // Finished initialization
|
||||
mDiskCacheLock.notifyAll(); // Wake any waiting threads
|
||||
mThumbnailCacheStarting = false; // Finished initialization
|
||||
thumbnailDiskCacheLock.notifyAll(); // Wake any waiting threads
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class AsyncDrawable extends BitmapDrawable {
|
||||
private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
|
||||
|
||||
public AsyncDrawable(Resources res, Bitmap bitmap,
|
||||
ThumbnailGenerationTask bitmapWorkerTask) {
|
||||
super(res, bitmap);
|
||||
bitmapWorkerTaskReference =
|
||||
new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
|
||||
}
|
||||
|
||||
public ThumbnailGenerationTask getBitmapWorkerTask() {
|
||||
return bitmapWorkerTaskReference.get();
|
||||
}
|
||||
}
|
||||
|
||||
class ThumbnailGenerationTask extends AsyncTask<OCFile, Void, Bitmap> {
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
private OCFile file;
|
||||
|
||||
class BitmapWorkerTask extends AsyncTask<OCFile, Void, Bitmap> {
|
||||
private final ImageView fileIcon;
|
||||
|
||||
public BitmapWorkerTask(ImageView fileIcon) {
|
||||
this.fileIcon = fileIcon;
|
||||
public ThumbnailGenerationTask(ImageView imageView) {
|
||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
||||
imageViewReference = new WeakReference<ImageView>(imageView);
|
||||
}
|
||||
|
||||
// Decode image in background.
|
||||
@Override
|
||||
protected Bitmap doInBackground(OCFile... params) {
|
||||
OCFile file = params[0];
|
||||
file = params[0];
|
||||
final String imageKey = String.valueOf(file.getRemoteId());
|
||||
|
||||
// Check disk cache in background thread
|
||||
|
@ -160,64 +186,72 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
|
||||
} else {
|
||||
// Download thumbnail from server
|
||||
DefaultHttpClient httpclient = new DefaultHttpClient();
|
||||
try {
|
||||
httpclient.getCredentialsProvider().setCredentials(
|
||||
new AuthScope(mClient.getBaseUri().toString().replace("https://", ""), 443),
|
||||
new UsernamePasswordCredentials(mClient.getCredentials().getUsername(), mClient.getCredentials().getAuthToken()));
|
||||
|
||||
|
||||
// TODO change to user preview.png
|
||||
//HttpGet httpget = new HttpGet(mClient.getBaseUri() + "/index.php/core/preview.png?file="+URLEncoder.encode(file.getRemotePath(), "UTF-8")+"&x=36&y=36&forceIcon=1");
|
||||
HttpGet httpget = new HttpGet(mClient.getBaseUri() + "/ocs/v1.php/thumbnail?x=50&y=50&path=" + URLEncoder.encode(file.getRemotePath(), "UTF-8"));
|
||||
HttpResponse response = httpclient.execute(httpget);
|
||||
HttpEntity entity = response.getEntity();
|
||||
|
||||
if (entity != null) {
|
||||
byte[] bytes = EntityUtils.toByteArray(entity);
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||
thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
|
||||
|
||||
// Add thumbnail to cache
|
||||
if (thumbnail != null){
|
||||
addBitmapToCache(imageKey, thumbnail);
|
||||
}
|
||||
}
|
||||
} catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
httpclient.getConnectionManager().shutdown();
|
||||
}
|
||||
// Commented out as maybe changes to client library are needed
|
||||
// DefaultHttpClient httpclient = new DefaultHttpClient();
|
||||
// try {
|
||||
// httpclient.getCredentialsProvider().setCredentials(
|
||||
// new AuthScope(mClient.getBaseUri().toString().replace("https://", ""), 443),
|
||||
// new UsernamePasswordCredentials(mClient.getCredentials().getUsername(), mClient.getCredentials().getAuthToken()));
|
||||
//
|
||||
//
|
||||
// HttpGet httpget = new HttpGet(mClient.getBaseUri() + "/ocs/v1.php/thumbnail?x=50&y=50&path=" + URLEncoder.encode(file.getRemotePath(), "UTF-8"));
|
||||
// HttpResponse response = httpclient.execute(httpget);
|
||||
// HttpEntity entity = response.getEntity();
|
||||
//
|
||||
// if (entity != null) {
|
||||
// byte[] bytes = EntityUtils.toByteArray(entity);
|
||||
// Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||
// thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
|
||||
//
|
||||
// // Add thumbnail to cache
|
||||
// if (thumbnail != null){
|
||||
// addBitmapToCache(imageKey, thumbnail);
|
||||
// }
|
||||
// }
|
||||
// } catch(Exception e){
|
||||
// e.printStackTrace();
|
||||
// }finally {
|
||||
// httpclient.getConnectionManager().shutdown();
|
||||
// }
|
||||
}
|
||||
}
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Bitmap bitmap){
|
||||
if (bitmap != null){
|
||||
fileIcon.setImageBitmap(bitmap);
|
||||
if (isCancelled()) {
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
if (imageViewReference != null && bitmap != null) {
|
||||
final ImageView imageView = imageViewReference.get();
|
||||
final ThumbnailGenerationTask bitmapWorkerTask =
|
||||
getBitmapWorkerTask(imageView);
|
||||
if (this == bitmapWorkerTask && imageView != null) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addBitmapToCache(String key, Bitmap bitmap) {
|
||||
synchronized (mDiskCacheLock) {
|
||||
if (mDiskLruCache != null && mDiskLruCache.getBitmap(key) == null) {
|
||||
mDiskLruCache.put(key, bitmap);
|
||||
synchronized (thumbnailDiskCacheLock) {
|
||||
if (mThumbnailCache != null && mThumbnailCache.getBitmap(key) == null) {
|
||||
mThumbnailCache.put(key, bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap getBitmapFromDiskCache(String key) {
|
||||
synchronized (mDiskCacheLock) {
|
||||
synchronized (thumbnailDiskCacheLock) {
|
||||
// Wait while disk cache is started from background thread
|
||||
while (mDiskCacheStarting) {
|
||||
while (mThumbnailCacheStarting) {
|
||||
try {
|
||||
mDiskCacheLock.wait();
|
||||
thumbnailDiskCacheLock.wait();
|
||||
} catch (InterruptedException e) {}
|
||||
}
|
||||
if (mDiskLruCache != null) {
|
||||
return (Bitmap) mDiskLruCache.getBitmap(key);
|
||||
if (mThumbnailCache != null) {
|
||||
return (Bitmap) mThumbnailCache.getBitmap(key);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -321,20 +355,23 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
|
||||
}
|
||||
checkBoxV.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
// first set thumbnail according to Mimetype, prevents empty thumbnails
|
||||
fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));
|
||||
}
|
||||
|
||||
// get Thumbnail if file is image
|
||||
if (file.isImage()){
|
||||
// Thumbnail in Cache?
|
||||
// Thumbnail in Cache?
|
||||
Bitmap thumbnail = getBitmapFromDiskCache(String.valueOf(file.getRemoteId()));
|
||||
if (thumbnail != null){
|
||||
fileIcon.setImageBitmap(thumbnail);
|
||||
} else {
|
||||
// generate new Thumbnail
|
||||
new BitmapWorkerTask(fileIcon).execute(file);
|
||||
if (cancelPotentialWork(file, fileIcon)) {
|
||||
final ThumbnailGenerationTask task = new ThumbnailGenerationTask(fileIcon);
|
||||
final AsyncDrawable asyncDrawable =
|
||||
new AsyncDrawable(mContext.getResources(), defaultImg, task);
|
||||
fileIcon.setImageDrawable(asyncDrawable);
|
||||
task.execute(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,6 +410,35 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
|
||||
return view;
|
||||
}
|
||||
|
||||
public static boolean cancelPotentialWork(OCFile file, ImageView imageView) {
|
||||
final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
|
||||
|
||||
if (bitmapWorkerTask != null) {
|
||||
final OCFile bitmapData = bitmapWorkerTask.file;
|
||||
// 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;
|
||||
}
|
||||
|
||||
private static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {
|
||||
if (imageView != null) {
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AsyncDrawable) {
|
||||
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
|
||||
return asyncDrawable.getBitmapWorkerTask();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package com.owncloud.android.ui.adapter;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
|
||||
public class Utils {
|
||||
public static final int IO_BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
private Utils() {};
|
||||
|
||||
public static boolean isExternalStorageRemovable() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
return Environment.isExternalStorageRemovable();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static File getExternalCacheDir(Context context) {
|
||||
if (hasExternalCacheDir()) {
|
||||
return context.getExternalCacheDir();
|
||||
}
|
||||
|
||||
// Before Froyo we need to construct the external cache dir ourselves
|
||||
final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
|
||||
return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
|
||||
}
|
||||
|
||||
public static boolean hasExternalCacheDir() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue