Merge branch 'develop' of https://github.com/tobiasKaminsky/android into develop
authortobiasKaminsky <tobias@kaminsky.me>
Sat, 9 Aug 2014 08:20:07 +0000 (10:20 +0200)
committertobiasKaminsky <tobias@kaminsky.me>
Sat, 9 Aug 2014 08:20:07 +0000 (10:20 +0200)
Conflicts:
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

.classpath
lint.xml
res/layout/image_fragment.xml [new file with mode: 0644]
res/layout/image_item.xml [new file with mode: 0644]
res/values-gl/strings.xml
res/values-ja-rJP/strings.xml
res/values-nl/strings.xml
src/com/owncloud/android/ui/adapter/DiskLruImageCache.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/Utils.java [new file with mode: 0644]
third_party/disklrucache-2.0.2.jar [new file with mode: 0644]

index 7bc01d9..fa15a28 100644 (file)
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="src" path="gen"/>
        <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
        <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
        <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>
index ee0eead..ce54dad 100644 (file)
--- a/lint.xml
+++ b/lint.xml
@@ -1,3 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
+    <issue id="NewApi">
+        <ignore path="src/com/owncloud/android/ui/adapter/Utils.java" />
+    </issue>
 </lint>
\ No newline at end of file
diff --git a/res/layout/image_fragment.xml b/res/layout/image_fragment.xml
new file mode 100644 (file)
index 0000000..340ee03
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  ownCloud Android client application
+
+  Copyright (C) 2012  Bartek Przybylski
+  Copyright (C) 2012-2013 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+       android:layout_width="0dp"
+       android:layout_height="match_parent"
+       android:layout_weight="1" >
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh_files"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" >
+
+        <com.owncloud.android.ui.ExtendedListView
+            android:id="@+id/list_root"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+        
+    </android.support.v4.widget.SwipeRefreshLayout>
+
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh_files_emptyView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone" >
+
+        <GridView
+            android:id="@+id/grid_list_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:numColumns="3" />
+    </android.support.v4.widget.SwipeRefreshLayout>
+</FrameLayout>
diff --git a/res/layout/image_item.xml b/res/layout/image_item.xml
new file mode 100644 (file)
index 0000000..bd9f8d7
--- /dev/null
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\r
+  Copyright (C) 2012-2013 ownCloud Inc.\r
+\r
+  This program is free software: you can redistribute it and/or modify\r
+  it under the terms of the GNU General Public License version 2,\r
+  as published by the Free Software Foundation.\r
+\r
+  This program is distributed in the hope that it will be useful,\r
+  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+  GNU General Public License for more details.\r
+\r
+  You should have received a copy of the GNU General Public License\r
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+  \r
+-->\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    android:id="@+id/ListItemLayout"\r
+    android:layout_width="fill_parent"\r
+    android:layout_height="160dp"\r
+    android:background="@drawable/list_selector"\r
+    android:orientation="horizontal" >\r
+\r
+    <ImageView\r
+        android:id="@+id/imageView1"\r
+        android:layout_width="150dp"\r
+        android:layout_height="150dp"\r
+        android:layout_marginBottom="5dp"\r
+        android:layout_marginLeft="9dp"\r
+        android:layout_marginTop="5dp"\r
+        android:src="@drawable/ic_menu_archive" />\r
+\r
+    <FrameLayout\r
+        android:id="@+id/imageItemFrame"\r
+        android:layout_width="56dp"\r
+        android:layout_height="56dp"\r
+        android:focusable="false"\r
+        android:focusableInTouchMode="false" >\r
+\r
+        <ImageView\r
+            android:id="@+id/sharedIcon"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_marginBottom="4dp"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:src="@drawable/sharedlink" />\r
+\r
+        <ImageView\r
+            android:id="@+id/sharedWithMeIcon"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:layout_marginTop="4dp"\r
+            android:src="@drawable/shared_with_me" />\r
+\r
+        <ImageView\r
+            android:id="@+id/custom_checkbox"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:src="@android:drawable/checkbox_off_background" />\r
+\r
+        <ImageView\r
+            android:id="@+id/imageView2"\r
+            android:layout_width="32dp"\r
+            android:layout_height="32dp"\r
+            android:layout_gravity="center_vertical"\r
+            android:layout_marginLeft="22dp"\r
+            android:src="@drawable/local_file_indicator" />\r
+\r
+        <TextView\r
+            android:id="@+id/Filename"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:ellipsize="middle"\r
+            android:singleLine="true"\r
+            android:text="TextView"\r
+            android:textColor="#303030"\r
+            android:textSize="16dip" />\r
+\r
+        <ImageView\r
+            android:id="@+id/imageView3"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_gravity="bottom|right"\r
+            android:layout_marginBottom="10dp"\r
+            android:layout_marginRight="2dp"\r
+            android:src="@drawable/ic_favorite" />\r
+\r
+        <TextView\r
+            android:id="@+id/last_mod"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_weight=".5"\r
+            android:text="TextView"\r
+            android:textColor="@color/list_item_lastmod_and_filesize_text"\r
+            android:textSize="12dip" />\r
+\r
+        <TextView\r
+            android:id="@+id/file_size"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_weight=".5"\r
+            android:gravity="right"\r
+            android:text="TextView"\r
+            android:textColor="@color/list_item_lastmod_and_filesize_text"\r
+            android:textSize="12dip" />\r
+    </FrameLayout>\r
+\r
+</LinearLayout>
\ No newline at end of file
index 3cb2e19..2bc0b28 100644 (file)
@@ -49,8 +49,9 @@
   <string name="uploader_wrn_no_content_text">Non se recibiu contido. Non hai nada para enviar.</string>
   <string name="uploader_error_forbidden_content">%1$s non ten permiso para acceder ao contido compartido</string>
   <string name="uploader_info_uploading">Enviando</string>
-  <string name="file_list_empty">Aquí non hai nada. Envíe algo.</string>
+  <string name="file_list_empty">Aquí non hai nada. Envíe algo!</string>
   <string name="file_list_loading">Cargando...</string>
+  <string name="local_file_list_empty">Non hai ficheiros neste cartafol.</string>
   <string name="filedetails_select_file">Prema nun ficheiro para que amose a información adicional.</string>
   <string name="filedetails_size">Tamaño:</string>
   <string name="filedetails_type">Tipo:</string>
index 8a100a5..59cc925 100644 (file)
@@ -51,6 +51,7 @@
   <string name="uploader_info_uploading">アップロード中</string>
   <string name="file_list_empty">ここには何もありません。何かアップロードしてください。</string>
   <string name="file_list_loading">読込中 ...</string>
+  <string name="local_file_list_empty">このフォルダにはファイルはありません。</string>
   <string name="filedetails_select_file">ファイルをタップすると追加情報が表示されます。</string>
   <string name="filedetails_size">サイズ:</string>
   <string name="filedetails_type">タイプ:</string>
   <string name="network_error_connect_timeout_exception">サーバーからの応答を待っている間にエラーが発生しました。操作を完了することができません。</string>
   <string name="network_host_not_available">操作を完了することができません。サーバーが利用できません。</string>
   <string name="empty"></string>
+  <string name="forbidden_permissions">権限 %s がありません</string>
+  <string name="forbidden_permissions_rename">ファイル名の変更</string>
+  <string name="forbidden_permissions_delete">ファイルを削除</string>
+  <string name="share_link_forbidden_permissions">ファイルを共有</string>
+  <string name="unshare_link_forbidden_permissions">ファイルの共有を解除</string>
+  <string name="forbidden_permissions_create">ファイルを作成</string>
+  <string name="uploader_upload_forbidden_permissions">フォルダをアップロード</string>
+  <string name="downloader_download_file_not_found">ファイルはサーバー上で利用できません</string>
 </resources>
index fec77a4..9604d2b 100644 (file)
@@ -51,6 +51,7 @@
   <string name="uploader_info_uploading">Uploaden</string>
   <string name="file_list_empty">Er bevindt zich hier niets. Upload een bestand!</string>
   <string name="file_list_loading">Laden ...</string>
+  <string name="local_file_list_empty">Er staan geen bestanden in deze map.</string>
   <string name="filedetails_select_file">Druk op een bestand om extra informatie weer te geven</string>
   <string name="filedetails_size">Grootte:</string>
   <string name="filedetails_type">Type:</string>
diff --git a/src/com/owncloud/android/ui/adapter/DiskLruImageCache.java b/src/com/owncloud/android/ui/adapter/DiskLruImageCache.java
new file mode 100644 (file)
index 0000000..5b401c2
--- /dev/null
@@ -0,0 +1,172 @@
+package com.owncloud.android.ui.adapter;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.util.Log;
+
+import com.jakewharton.disklrucache.DiskLruCache;
+import com.owncloud.android.BuildConfig;
+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 static final int VALUE_COUNT = 1;
+    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 );
+                mCompressFormat = compressFormat;
+                mCompressQuality = quality;
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+    }
+
+    private boolean writeBitmapToFile( Bitmap bitmap, DiskLruCache.Editor editor )
+        throws IOException, FileNotFoundException {
+        OutputStream out = null;
+        try {
+            out = new BufferedOutputStream( editor.newOutputStream( 0 ), Utils.IO_BUFFER_SIZE );
+            return bitmap.compress( mCompressFormat, mCompressQuality, out );
+        } finally {
+            if ( out != null ) {
+                out.close();
+            }
+        }
+    }
+
+    private File getDiskCacheDir(Context context, String uniqueName) {
+
+    // 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();
+
+        Log_OC.d("DiskCache", "create dir: " + cachePath + File.separator + uniqueName);
+                    
+        return new File(cachePath + File.separator + uniqueName);
+    }
+
+    public void put( String key, Bitmap data ) {
+
+        DiskLruCache.Editor editor = null;
+        try {
+            editor = mDiskCache.edit( key );
+            if ( editor == null ) {
+                return;
+            }
+
+            if( writeBitmapToFile( data, editor ) ) {               
+                mDiskCache.flush();
+                editor.commit();
+                if ( BuildConfig.DEBUG ) {
+                   Log.d( "cache_test_DISK_", "image put on disk cache " + key );
+                }
+            } else {
+                editor.abort();
+                if ( BuildConfig.DEBUG ) {
+                    Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
+                }
+            }   
+        } catch (IOException e) {
+            if ( BuildConfig.DEBUG ) {
+                Log.d( "cache_test_DISK_", "ERROR on: image put on disk cache " + key );
+            }
+            try {
+                if ( editor != null ) {
+                    editor.abort();
+                }
+            } catch (IOException ignored) {
+            }           
+        }
+
+    }
+
+    public Bitmap getBitmap( String key ) {
+
+        Bitmap bitmap = null;
+        DiskLruCache.Snapshot snapshot = null;
+        try {
+
+            snapshot = mDiskCache.get( key );
+            if ( snapshot == null ) {
+                return null;
+            }
+            final InputStream in = snapshot.getInputStream( 0 );
+            if ( in != null ) {
+                final BufferedInputStream buffIn = 
+                new BufferedInputStream( in, Utils.IO_BUFFER_SIZE );
+                bitmap = BitmapFactory.decodeStream( buffIn );              
+            }   
+        } catch ( IOException e ) {
+            e.printStackTrace();
+        } finally {
+            if ( snapshot != null ) {
+                snapshot.close();
+            }
+        }
+
+        if ( BuildConfig.DEBUG ) {
+            Log.d( "cache_test_DISK_", bitmap == null ? "not found" : "image read from disk " + key);
+        }
+
+        return bitmap;
+
+    }
+
+    public boolean containsKey( String key ) {
+
+        boolean contained = false;
+        DiskLruCache.Snapshot snapshot = null;
+        try {
+            snapshot = mDiskCache.get( key );
+            contained = snapshot != null;
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if ( snapshot != null ) {
+                snapshot.close();
+            }
+        }
+
+        return contained;
+
+    }
+
+    public void clearCache() {
+        if ( BuildConfig.DEBUG ) {
+            Log.d( "cache_test_DISK_", "disk cache CLEARED");
+        }
+        try {
+            mDiskCache.delete();
+        } catch ( IOException e ) {
+            e.printStackTrace();
+        }
+    }
+
+    public File getCacheFolder() {
+        return mDiskCache.getDirectory();
+    }
+
+}
\ No newline at end of file
index b1e38e8..03f5ddc 100644 (file)
  */\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
+<<<<<<< HEAD
+import android.graphics.Bitmap.CompressFormat;\r
 import android.graphics.BitmapFactory;\r
 import android.media.ThumbnailUtils;\r
+import android.os.AsyncTask;\r
+=======
+import android.graphics.BitmapFactory;\r
+import android.media.ThumbnailUtils;\r
+>>>>>>> c0dc4c42d71eb9593ff48a02a8af74bd7df8776e
 import android.util.TypedValue;\r
 import android.view.LayoutInflater;\r
 import android.view.View;\r
@@ -41,9 +53,21 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 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
@@ -62,11 +86,144 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
     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
@@ -168,6 +325,24 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                     }\r
                     checkBoxV.setVisibility(View.VISIBLE);\r
                 }\r
+<<<<<<< HEAD
+                \r
+                // first set thumbnail according to Mimetype, prevents empty thumbnails\r
+                fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));\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
+=======
 \r
                 // generate Thumbnail if file is available local and image\r
                 if (file.isDown() && file.isImage()){\r
@@ -180,12 +355,12 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                     fileIcon.setImageResource(DisplayUtils.getResourceId(file.getMimetype(), file.getFileName()));  \r
                 }\r
 \r
+>>>>>>> c0dc4c42d71eb9593ff48a02a8af74bd7df8776e
                 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
diff --git a/src/com/owncloud/android/ui/adapter/Utils.java b/src/com/owncloud/android/ui/adapter/Utils.java
new file mode 100644 (file)
index 0000000..181cc92
--- /dev/null
@@ -0,0 +1,35 @@
+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;
+    }
+
+}
diff --git a/third_party/disklrucache-2.0.2.jar b/third_party/disklrucache-2.0.2.jar
new file mode 100644 (file)
index 0000000..ca7907d
Binary files /dev/null and b/third_party/disklrucache-2.0.2.jar differ