*/\r
package com.owncloud.android.ui.adapter;\r
\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.net.URLEncoder;\r
import java.util.Vector;\r
\r
import android.accounts.Account;\r
+import android.accounts.AuthenticatorException;\r
+import android.accounts.OperationCanceledException;\r
import android.content.Context;\r
+import android.content.res.Resources;\r
+import android.graphics.Bitmap;\r
+import android.graphics.Bitmap.CompressFormat;\r
+import android.graphics.BitmapFactory;\r
+import android.media.ThumbnailUtils;\r
+import android.os.AsyncTask;\r
+import android.util.TypedValue;\r
import android.view.LayoutInflater;\r
import android.view.View;\r
import android.view.ViewGroup;\r
import com.owncloud.android.datamodel.OCFile;\r
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;\r
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;\r
+import com.owncloud.android.lib.common.OwnCloudAccount;\r
+import com.owncloud.android.lib.common.OwnCloudClient;\r
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;\r
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;\r
import com.owncloud.android.ui.activity.ComponentsGetter;\r
import com.owncloud.android.utils.DisplayUtils;\r
\r
+import org.apache.http.HttpEntity;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.auth.AuthScope;\r
+import org.apache.http.auth.UsernamePasswordCredentials;\r
+import org.apache.http.client.methods.HttpGet;\r
+import org.apache.http.impl.client.DefaultHttpClient;\r
+import org.apache.http.util.EntityUtils;\r
+\r
\r
/**\r
* This Adapter populates a ListView with all files and folders in an ownCloud\r
private FileDataStorageManager mStorageManager;
private Account mAccount;
private ComponentsGetter mTransferServiceGetter;\r
- \r
+ private final Object mDiskCacheLock = new Object();\r
+ private DiskLruImageCache mDiskLruCache;\r
+ private boolean mDiskCacheStarting = true;\r
+ private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB\r
+ private CompressFormat mCompressFormat = CompressFormat.JPEG;\r
+ private int mCompressQuality = 70;\r
+ private OwnCloudClient mClient;\r
+ \r
public FileListListAdapter(Context context, ComponentsGetter transferServiceGetter) {\r
mContext = context;\r
mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
mTransferServiceGetter = transferServiceGetter;\r
+ \r
+ // Initialise disk cache on background thread\r
+ new InitDiskCacheTask().execute();\r
+ }\r
+ \r
+ class InitDiskCacheTask extends AsyncTask<File, Void, Void> {\r
+ @Override\r
+ protected Void doInBackground(File... params) {\r
+ synchronized (mDiskCacheLock) {\r
+ mDiskLruCache = new DiskLruImageCache(mContext, "thumbnailCache", DISK_CACHE_SIZE, mCompressFormat,mCompressQuality);\r
+ \r
+ try {\r
+ OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);\r
+ mClient = OwnCloudClientManagerFactory.getDefaultSingleton().\r
+ getClientFor(ocAccount, mContext);\r
+ } catch (AccountNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (AuthenticatorException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (OperationCanceledException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (IOException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+\r
+ mDiskCacheStarting = false; // Finished initialization\r
+ mDiskCacheLock.notifyAll(); // Wake any waiting threads\r
+ }\r
+ return null;\r
+ }\r
+ }\r
+\r
+ class BitmapWorkerTask extends AsyncTask<OCFile, Void, Bitmap> {\r
+ private final ImageView fileIcon;\r
+ \r
+ public BitmapWorkerTask(ImageView fileIcon) {\r
+ this.fileIcon = fileIcon;\r
+ }\r
+\r
+ // Decode image in background.\r
+ @Override\r
+ protected Bitmap doInBackground(OCFile... params) {\r
+ OCFile file = params[0];\r
+ final String imageKey = String.valueOf(file.getRemoteId());\r
+\r
+ // Check disk cache in background thread\r
+ Bitmap thumbnail = getBitmapFromDiskCache(imageKey);\r
+\r
+ // Not found in disk cache\r
+ if (thumbnail == null) { \r
+ // Converts dp to pixel\r
+ Resources r = mContext.getResources();\r
+ int px = (int) Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics()));\r
+ \r
+ if (file.isDown()){\r
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getStoragePath());\r
+ thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);\r
+ \r
+ // Add thumbnail to cache\r
+ addBitmapToCache(imageKey, thumbnail);\r
+\r
+ } else {\r
+ // Download thumbnail from server\r
+ DefaultHttpClient httpclient = new DefaultHttpClient();\r
+ try {\r
+ httpclient.getCredentialsProvider().setCredentials(\r
+ new AuthScope(mClient.getBaseUri().toString().replace("https://", ""), 443), \r
+ new UsernamePasswordCredentials(mClient.getCredentials().getUsername(), mClient.getCredentials().getAuthToken()));\r
+ \r
+\r
+ // TODO change to user preview.png\r
+ HttpGet httpget = new HttpGet(mClient.getBaseUri() + "/ocs/v1.php/thumbnail?path=" + URLEncoder.encode(file.getRemotePath(), "UTF-8"));\r
+ HttpResponse response = httpclient.execute(httpget);\r
+ HttpEntity entity = response.getEntity();\r
+ \r
+ if (entity != null) {\r
+ byte[] bytes = EntityUtils.toByteArray(entity);\r
+ Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);\r
+ thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);\r
+ \r
+ // Add thumbnail to cache\r
+ if (thumbnail != null){\r
+ addBitmapToCache(imageKey, thumbnail);\r
+ }\r
+ \r
+ }\r
+ } catch(Exception e){\r
+ e.printStackTrace();\r
+ }finally {\r
+ httpclient.getConnectionManager().shutdown();\r
+ }\r
+ } \r
+ }\r
+ return thumbnail;\r
+ }\r
+ \r
+ protected void onPostExecute(Bitmap bitmap){\r
+ fileIcon.setImageBitmap(bitmap);\r
+ }\r
+ }\r
+ \r
+ public void addBitmapToCache(String key, Bitmap bitmap) {\r
+ synchronized (mDiskCacheLock) {\r
+ if (mDiskLruCache != null && mDiskLruCache.getBitmap(key) == null) {\r
+ mDiskLruCache.put(key, bitmap);\r
+ }\r
+ }\r
+ }\r
+\r
+ public Bitmap getBitmapFromDiskCache(String key) {\r
+ synchronized (mDiskCacheLock) {\r
+ // Wait while disk cache is started from background thread\r
+ while (mDiskCacheStarting) {\r
+ try {\r
+ mDiskCacheLock.wait();\r
+ } catch (InterruptedException e) {}\r
+ }\r
+ if (mDiskLruCache != null) {\r
+ return (Bitmap) mDiskLruCache.getBitmap(key);\r
+ }\r
+ }\r
+ return null;\r
}
\r
@Override\r
}\r
checkBoxV.setVisibility(View.VISIBLE);\r
}\r
-\r
+ \r
+ // first set thumbnail according to Mimetype, prevents empty thumbnails\r
fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\r
-\r
+ \r
+ // get Thumbnail if file is image\r
+ if (file.isImage()){\r
+ // Thumbnail in Cache?\r
+ Bitmap thumbnail = getBitmapFromDiskCache(String.valueOf(file.getRemoteId()));\r
+ if (thumbnail != null){\r
+ fileIcon.setImageBitmap(thumbnail);\r
+ } else {\r
+ // generate new Thumbnail\r
+ new BitmapWorkerTask(fileIcon).execute(file);\r
+ }\r
+ }\r
+ \r
if (checkIfFileIsSharedWithMe(file)) {\r
sharedWithMeIconV.setVisibility(View.VISIBLE);\r
}\r
} \r
else {\r
- \r
fileSizeV.setVisibility(View.INVISIBLE);\r
//fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
lastModV.setVisibility(View.VISIBLE);\r