Browse Source

Merge pull request #1399 from owncloud/uploadShowsFiles_Master

Upload shows files
Thomas Müller 9 years ago
parent
commit
ea2fe8cb4e

+ 3 - 4
res/layout/uploader_list_item_layout.xml

@@ -29,7 +29,7 @@
         android:layout_width="@dimen/file_icon_size"
         android:layout_width="@dimen/file_icon_size"
         android:layout_height="@dimen/file_icon_size"
         android:layout_height="@dimen/file_icon_size"
         android:layout_gravity="center_vertical|center"
         android:layout_gravity="center_vertical|center"
-        android:src="@drawable/ic_menu_archive" 
+        android:src="@drawable/ic_menu_archive"
         android:id="@+id/thumbnail"
         android:id="@+id/thumbnail"
         android:layout_marginRight="@dimen/standard_padding"/>
         android:layout_marginRight="@dimen/standard_padding"/>
     
     
@@ -37,9 +37,8 @@
         android:text="TextView" 
         android:text="TextView" 
         android:layout_width="fill_parent" 
         android:layout_width="fill_parent" 
         android:id="@+id/filename"
         android:id="@+id/filename"
-        android:layout_height="wrap_content" 
+        android:layout_height="wrap_content"
         android:textColor="@android:color/black"
         android:textColor="@android:color/black"
-		android:layout_gravity="center_vertical"
-        android:textSize="20dip"/>
+        android:textSize="16sp" />
     
     
 </LinearLayout>
 </LinearLayout>

+ 8 - 0
src/com/owncloud/android/datamodel/OCFile.java

@@ -436,6 +436,14 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         return mParentId;
         return mParentId;
     }
     }
 
 
+    /**
+     * get remote path of parent file
+     * @return remote path
+     */
+    public String getParentRemotePath() {
+        return new File(getRemotePath()).getParent();
+    }
+
     /**
     /**
      * Check, if this file needs updating
      * Check, if this file needs updating
      *
      *

+ 1 - 4
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -967,7 +967,7 @@ public class FileDisplayActivity extends HookActivity
                 String synchFolderRemotePath =
                 String synchFolderRemotePath =
                         intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);
                         intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);
                 RemoteOperationResult synchResult =
                 RemoteOperationResult synchResult =
-                        (RemoteOperationResult)intent.getSerializableExtra(
+                        (RemoteOperationResult) intent.getSerializableExtra(
                                 FileSyncAdapter.EXTRA_RESULT);
                                 FileSyncAdapter.EXTRA_RESULT);
                 boolean sameAccount = (getAccount() != null &&
                 boolean sameAccount = (getAccount() != null &&
                         accountName.equals(getAccount().name) && getStorageManager() != null);
                         accountName.equals(getAccount().name) && getStorageManager() != null);
@@ -1037,9 +1037,6 @@ public class FileDisplayActivity extends HookActivity
                     removeStickyBroadcast(intent);
                     removeStickyBroadcast(intent);
                     Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
                     Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
                     mProgressBar.setIndeterminate(mSyncInProgress);
                     mProgressBar.setIndeterminate(mSyncInProgress);
-                    //mProgressBar.setVisibility((mSyncInProgress) ? View.VISIBLE : View.INVISIBLE);
-                    //setSupportProgressBarIndeterminateVisibility(mSyncInProgress
-                    /*|| mRefreshSharesInProgress*/ //);
 
 
                     setBackgroundText();
                     setBackgroundText();
 
 

+ 218 - 80
src/com/owncloud/android/ui/activity/Uploader.java

@@ -30,15 +30,28 @@ import java.util.List;
 import java.util.Stack;
 import java.util.Stack;
 import java.util.Vector;
 import java.util.Vector;
 
 
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.RefreshFolderOperation;
 
 
 import android.accounts.Account;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountManager;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AlertDialog.Builder;
+import android.accounts.AuthenticatorException;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
 import android.app.Dialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
 import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface;
+import android.content.IntentFilter;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnClickListener;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.Intent;
@@ -49,7 +62,6 @@ import android.net.Uri;
 import android.os.Bundle;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.Parcelable;
 import android.preference.PreferenceManager;
 import android.preference.PreferenceManager;
-import android.provider.MediaStore;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Video;
 import android.provider.MediaStore.Video;
@@ -67,18 +79,11 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.EditText;
 import android.widget.ListView;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.ProgressBar;
-import android.widget.SimpleAdapter;
 import android.widget.Toast;
 import android.widget.Toast;
 
 
-import com.owncloud.android.MainApp;
-import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountAuthenticator;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.common.operations.RemoteOperation;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.syncadapter.FileSyncAdapter;
+import com.owncloud.android.ui.adapter.UploaderAdapter;
 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.utils.CopyTmpFileAsyncTask;
 import com.owncloud.android.utils.CopyTmpFileAsyncTask;
@@ -101,6 +106,9 @@ public class Uploader extends FileActivity
     private boolean mCreateDir;
     private boolean mCreateDir;
     private String mUploadPath;
     private String mUploadPath;
     private OCFile mFile;
     private OCFile mFile;
+
+    private SyncBroadcastReceiver mSyncBroadcastReceiver;
+    private boolean mSyncInProgress = false;
     private boolean mAccountSelected;
     private boolean mAccountSelected;
     private boolean mAccountSelectionShowing;
     private boolean mAccountSelectionShowing;
 
 
@@ -149,6 +157,13 @@ public class Uploader extends FileActivity
         if (mAccountSelected) {
         if (mAccountSelected) {
             setAccount((Account) savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT));
             setAccount((Account) savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT));
         }
         }
+
+        // Listen for sync messages
+        IntentFilter syncIntentFilter = new IntentFilter(RefreshFolderOperation.
+                EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
+        syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
+        mSyncBroadcastReceiver = new SyncBroadcastReceiver();
+        registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
     }
     }
 
 
     @Override
     @Override
@@ -199,6 +214,14 @@ public class Uploader extends FileActivity
         Log_OC.d(TAG, "onSaveInstanceState() end");
         Log_OC.d(TAG, "onSaveInstanceState() end");
     }
     }
 
 
+    @Override
+    protected void onDestroy(){
+        if (mSyncBroadcastReceiver != null) {
+            unregisterReceiver(mSyncBroadcastReceiver);
+        }
+        super.onDestroy();
+    }
+
     @Override
     @Override
     protected Dialog onCreateDialog(final int id) {
     protected Dialog onCreateDialog(final int id) {
         final AlertDialog.Builder builder = new Builder(this);
         final AlertDialog.Builder builder = new Builder(this);
@@ -230,8 +253,8 @@ public class Uploader extends FileActivity
                     if (android.os.Build.VERSION.SDK_INT >
                     if (android.os.Build.VERSION.SDK_INT >
                             android.os.Build.VERSION_CODES.ECLAIR_MR1) {
                             android.os.Build.VERSION_CODES.ECLAIR_MR1) {
                         // using string value since in API7 this
                         // using string value since in API7 this
-                        // constatn is not defined
-                        // in API7 < this constatant is defined in
+                        // constant is not defined
+                        // in API7 < this constant is defined in
                         // Settings.ADD_ACCOUNT_SETTINGS
                         // Settings.ADD_ACCOUNT_SETTINGS
                         // and Settings.EXTRA_AUTHORITIES
                         // and Settings.EXTRA_AUTHORITIES
                         Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
                         Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
@@ -319,12 +342,13 @@ public class Uploader extends FileActivity
 
 
     @Override
     @Override
     public void onBackPressed() {
     public void onBackPressed() {
-
         if (mParents.size() <= 1) {
         if (mParents.size() <= 1) {
             super.onBackPressed();
             super.onBackPressed();
             return;
             return;
         } else {
         } else {
             mParents.pop();
             mParents.pop();
+            String full_path = generatePath(mParents);
+            startSyncFolderOperation(getStorageManager().getFileByPath(full_path));
             populateDirectoryList();
             populateDirectoryList();
         }
         }
     }
     }
@@ -339,13 +363,16 @@ public class Uploader extends FileActivity
         // filter on dirtype
         // filter on dirtype
         Vector<OCFile> files = new Vector<OCFile>();
         Vector<OCFile> files = new Vector<OCFile>();
         for (OCFile f : tmpfiles)
         for (OCFile f : tmpfiles)
-            if (f.isFolder())
                 files.add(f);
                 files.add(f);
         if (files.size() < position) {
         if (files.size() < position) {
             throw new IndexOutOfBoundsException("Incorrect item selected");
             throw new IndexOutOfBoundsException("Incorrect item selected");
         }
         }
-        mParents.push(files.get(position).getFileName());
-        populateDirectoryList();
+        if (files.get(position).isFolder()){
+            OCFile folderToEnter = files.get(position);
+            startSyncFolderOperation(folderToEnter);
+            mParents.push(folderToEnter.getFileName());
+            populateDirectoryList();
+        }
     }
     }
 
 
     @Override
     @Override
@@ -420,19 +447,19 @@ public class Uploader extends FileActivity
         if (mFile != null) {
         if (mFile != null) {
             // TODO Enable when "On Device" is recovered ?
             // TODO Enable when "On Device" is recovered ?
             Vector<OCFile> files = getStorageManager().getFolderContent(mFile/*, false*/);
             Vector<OCFile> files = getStorageManager().getFolderContent(mFile/*, false*/);
-            List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
+            List<HashMap<String, OCFile>> data = new LinkedList<HashMap<String,OCFile>>();
             for (OCFile f : files) {
             for (OCFile f : files) {
-                HashMap<String, Object> h = new HashMap<String, Object>();
-                if (f.isFolder()) {
-                    h.put("dirname", f.getFileName());
+                HashMap<String, OCFile> h = new HashMap<String, OCFile>();
+                    h.put("dirname", f);
                     data.add(h);
                     data.add(h);
-                }
             }
             }
-            SimpleAdapter sa = new SimpleAdapter(this,
+            
+            UploaderAdapter sa = new UploaderAdapter(this,
                                                 data,
                                                 data,
                                                 R.layout.uploader_list_item_layout,
                                                 R.layout.uploader_list_item_layout,
                                                 new String[] {"dirname"},
                                                 new String[] {"dirname"},
-                                                new int[] {R.id.filename});
+                                                new int[] {R.id.filename},
+                                                getStorageManager(), getAccount());
             
             
             mListView.setAdapter(sa);
             mListView.setAdapter(sa);
             Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
             Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
@@ -444,6 +471,25 @@ public class Uploader extends FileActivity
             mListView.setOnItemClickListener(this);
             mListView.setOnItemClickListener(this);
         }
         }
     }
     }
+    
+    private void startSyncFolderOperation(OCFile folder) {
+        long currentSyncTime = System.currentTimeMillis(); 
+        
+        mSyncInProgress = true;
+        
+        // perform folder synchronization
+        RemoteOperation synchFolderOp = new RefreshFolderOperation( folder,
+                                                                        currentSyncTime, 
+                                                                        false,
+                                                                        false,
+                                                                        false,
+                                                                        getStorageManager(),
+                                                                        getAccount(),
+                                                                        getApplicationContext()
+                                                                      );
+        synchFolderOp.execute(getAccount(), this, null, null);
+    }
+
 
 
     private String generatePath(Stack<String> dirs) {
     private String generatePath(Stack<String> dirs) {
         String full_path = "";
         String full_path = "";
@@ -482,55 +528,54 @@ public class Uploader extends FileActivity
 
 
                 if (uri != null) {
                 if (uri != null) {
                     if (uri.getScheme().equals("content")) {
                     if (uri.getScheme().equals("content")) {
-                        String mimeType = getContentResolver().getType(uri);
-
-                        if (mimeType.contains("image")) {
-                            String[] CONTENT_PROJECTION = { Images.Media.DATA,
-                                    Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE,
-                                    Images.Media.SIZE };
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
-                                    null, null);
-                            c.moveToFirst();
-                            int index = c.getColumnIndex(Images.Media.DATA);
-                            data = c.getString(index);
-                            filePath = mUploadPath +
-                                    c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
-
-                        } else if (mimeType.contains("video")) {
-                            String[] CONTENT_PROJECTION = { Video.Media.DATA,
-                                   Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
-                                   Video.Media.SIZE, Video.Media.DATE_MODIFIED };
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
-                                   null, null);
-                            c.moveToFirst();
-                            int index = c.getColumnIndex(Video.Media.DATA);
-                            data = c.getString(index);
-                            filePath = mUploadPath +
-                                   c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME));
-                          
-                        } else if (mimeType.contains("audio")) {
-                            String[] CONTENT_PROJECTION = { Audio.Media.DATA,
-                                   Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE,
-                                   Audio.Media.SIZE };
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
-                                   null, null);
-                            c.moveToFirst();
-                            int index = c.getColumnIndex(Audio.Media.DATA);
-                            data = c.getString(index);
-                            filePath = mUploadPath +
-                                   c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME));
-
-                        } else  {
-                            Cursor cursor = getContentResolver().query(uri,
-                                   new String[]{MediaStore.MediaColumns.DISPLAY_NAME},
-                                   null, null, null);
-                            cursor.moveToFirst();
-                            int nameIndex = cursor.getColumnIndex(cursor.getColumnNames()[0]);
-                            if (nameIndex >= 0) {
-                               filePath = mUploadPath + cursor.getString(nameIndex);
-                            }
-                        }
-
+                       String mimeType = getContentResolver().getType(uri);
+
+                       if (mimeType.contains("image")) {
+                           String[] CONTENT_PROJECTION = { Images.Media.DATA, Images.Media.DISPLAY_NAME,
+                                                           Images.Media.MIME_TYPE, Images.Media.SIZE};
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           c.moveToFirst();
+                           int index = c.getColumnIndex(Images.Media.DATA);
+                           data = c.getString(index);
+                           local.add(data);
+                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
+
+                       }
+                       else if (mimeType.contains("video")) {
+                           String[] CONTENT_PROJECTION = { Video.Media.DATA, Video.Media.DISPLAY_NAME,
+                                                           Video.Media.MIME_TYPE, Video.Media.SIZE,
+                                                           Video.Media.DATE_MODIFIED };
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           c.moveToFirst();
+                           int index = c.getColumnIndex(Video.Media.DATA);
+                           data = c.getString(index);
+                           local.add(data);
+                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
+
+                       }
+                       else if (mimeType.contains("audio")) {
+                           String[] CONTENT_PROJECTION = { Audio.Media.DATA, Audio.Media.DISPLAY_NAME,
+                                                           Audio.Media.MIME_TYPE, Audio.Media.SIZE };
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           c.moveToFirst();
+                           int index = c.getColumnIndex(Audio.Media.DATA);
+                           data = c.getString(index);
+                           local.add(data);
+                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
+
+                       }
+                       else {
+                           filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
+                           // cut everything whats before mnt. It occured to me that sometimes apps send
+                           // their name into the URI
+                           if (filePath.contains("mnt")) {
+                              String splitedFilePath[] = filePath.split("/mnt");
+                              filePath = splitedFilePath[1];
+                           }
+                           final File file = new File(filePath);
+                           local.add(file.getAbsolutePath());
+                           remote.add(mUploadPath + file.getName());
+                       }
                     } else if (uri.getScheme().equals("file")) {
                     } else if (uri.getScheme().equals("file")) {
                         filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
                         filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
                                 "://", "");
                                 "://", "");
@@ -548,14 +593,11 @@ public class Uploader extends FileActivity
                     if (data == null) {
                     if (data == null) {
                         mRemoteCacheData.add(filePath);
                         mRemoteCacheData.add(filePath);
                         CopyTmpFileAsyncTask copyTask = new CopyTmpFileAsyncTask(this);
                         CopyTmpFileAsyncTask copyTask = new CopyTmpFileAsyncTask(this);
-                        Object[] params = { uri, filePath, mRemoteCacheData.size()-1,
+                        Object[] params = {uri, filePath, mRemoteCacheData.size() - 1,
                                 getAccount().name, getContentResolver()};
                                 getAccount().name, getContentResolver()};
                         mNumCacheFile++;
                         mNumCacheFile++;
                         showWaitingCopyDialog();
                         showWaitingCopyDialog();
                         copyTask.execute(params);
                         copyTask.execute(params);
-                    } else {
-                        remote.add(filePath);
-                        local.add(data);
                     }
                     }
                 }
                 }
                 else {
                 else {
@@ -682,8 +724,104 @@ public class Uploader extends FileActivity
         }
         }
         return retval;
         return retval;
     }
     }
+    
+    private OCFile getCurrentFolder(){
+        OCFile file = mFile;
+        if (file != null) {
+            if (file.isFolder()) {
+                return file;
+            } else if (getStorageManager() != null) {
+                return getStorageManager().getFileByPath(file.getParentRemotePath());
+            }
+        }
+        return null;
+    }
+    
+    private void browseToRoot() {
+        OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
+        mFile = root;
+        startSyncFolderOperation(root);
+    }
+    
+    private class SyncBroadcastReceiver extends BroadcastReceiver {
+
+        /**
+         * {@link BroadcastReceiver} to enable syncing feedback in UI
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            try {
+                String event = intent.getAction();
+                Log_OC.d(TAG, "Received broadcast " + event);
+                String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
+                String synchFolderRemotePath =
+                        intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);
+                RemoteOperationResult synchResult =
+                        (RemoteOperationResult) intent.getSerializableExtra(
+                                FileSyncAdapter.EXTRA_RESULT);
+                boolean sameAccount = (getAccount() != null &&
+                        accountName.equals(getAccount().name) && getStorageManager() != null);
+
+                if (sameAccount) {
+
+                    if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
+                        mSyncInProgress = true;
+
+                    } else {
+                        OCFile currentFile = (mFile == null) ? null :
+                                getStorageManager().getFileByPath(mFile.getRemotePath());
+                        OCFile currentDir = (getCurrentFolder() == null) ? null :
+                                getStorageManager().getFileByPath(getCurrentFolder().getRemotePath());
+
+                        if (currentDir == null) {
+                            // current folder was removed from the server 
+                            Toast.makeText(context,
+                                    String.format(
+                                            getString(R.string.sync_current_folder_was_removed),
+                                            getCurrentFolder().getFileName()),
+                                    Toast.LENGTH_LONG)
+                                    .show();
+                            browseToRoot();
+
+                        } else {
+                            if (currentFile == null && !mFile.isFolder()) {
+                                // currently selected file was removed in the server, and now we know it
+                                currentFile = currentDir;
+                            }
+
+                            if (synchFolderRemotePath != null &&
+                                    currentDir.getRemotePath().equals(synchFolderRemotePath)) {
+                                populateDirectoryList();
+                            }
+                            mFile = currentFile;
+                        }
 
 
+                        mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) &&
+                                !RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
+
+                        if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
+                                equals(event) &&
+                                /// TODO refactor and make common
+                                synchResult != null && !synchResult.isSuccess() &&
+                                (synchResult.getCode() == ResultCode.UNAUTHORIZED ||
+                                        synchResult.isIdPRedirection() ||
+                                        (synchResult.isException() && synchResult.getException()
+                                                instanceof AuthenticatorException))) {
+
+                            requestCredentialsUpdate(context);
+                        }
+                    }
+                    removeStickyBroadcast(intent);
+                    Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
 
 
+                }
+            } catch (RuntimeException e) {
+                // avoid app crashes after changing the serial id of RemoteOperationResult 
+                // in owncloud library with broadcast notifications pending to process
+                removeStickyBroadcast(intent);
+            }
+        }
+    }
     /**
     /**
      * Process the result of CopyTmpFileAsyncTask
      * Process the result of CopyTmpFileAsyncTask
      * @param result
      * @param result
@@ -708,9 +846,9 @@ public class Uploader extends FileActivity
             Toast.makeText(this, message, Toast.LENGTH_LONG).show();
             Toast.makeText(this, message, Toast.LENGTH_LONG).show();
             Log_OC.d(TAG, message);
             Log_OC.d(TAG, message);
         }
         }
-
     }
     }
-/**
+
+    /**
      * Show waiting for copy dialog
      * Show waiting for copy dialog
      */
      */
     public void showWaitingCopyDialog() {
     public void showWaitingCopyDialog() {

+ 116 - 0
src/com/owncloud/android/ui/adapter/UploaderAdapter.java

@@ -0,0 +1,116 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Tobias Kaminsky
+ *   Copyright (C) 2016 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/>.
+ *
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncDrawable;
+import com.owncloud.android.utils.MimetypeIconUtil;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class UploaderAdapter extends SimpleAdapter {
+    
+    private Context mContext;
+    private Account mAccount;
+    private FileDataStorageManager mStorageManager;
+    private LayoutInflater inflater;
+
+    public UploaderAdapter(Context context,
+                           List<? extends Map<String, ?>> data, int resource, String[] from,
+                           int[] to, FileDataStorageManager storageManager, Account account) {
+        super(context, data, resource, from, to);
+        mAccount = account;
+        mStorageManager = storageManager;
+        mContext = context;
+        inflater = (LayoutInflater) mContext
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View vi = convertView;
+        if (convertView == null)
+            vi = inflater.inflate(R.layout.uploader_list_item_layout, null);
+
+        HashMap<String, OCFile> data = (HashMap<String, OCFile>) getItem(position);
+        OCFile file = data.get("dirname");
+
+        TextView filename = (TextView) vi.findViewById(R.id.filename);
+        filename.setText(file.getFileName());
+        
+        ImageView fileIcon = (ImageView) vi.findViewById(R.id.thumbnail);
+        fileIcon.setTag(file.getFileId());
+
+        // TODO enable after #1277 is merged
+//        TextView lastModV = (TextView) vi.findViewById(R.id.last_mod);
+//        lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file));
+        
+        // get Thumbnail if file is image
+        if (file.isImage() && file.getRemoteId() != null){
+             // Thumbnail in Cache?
+            Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                    String.valueOf(file.getRemoteId())
+            );
+            if (thumbnail != null && !file.needsUpdateThumbnail()){
+                fileIcon.setImageBitmap(thumbnail);
+            } else {
+                // generate new Thumbnail
+                if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {
+                    final ThumbnailsCacheManager.ThumbnailGenerationTask task = 
+                            new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, mStorageManager, 
+                                    mAccount);
+                    if (thumbnail == null) {
+                        thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                    }
+                    final AsyncDrawable asyncDrawable = new AsyncDrawable(
+                            mContext.getResources(), 
+                            thumbnail, 
+                            task
+                    );
+                    fileIcon.setImageDrawable(asyncDrawable);
+                    task.execute(file);
+                }
+            }
+        } else {
+            fileIcon.setImageResource(
+                    MimetypeIconUtil.getFileTypeIconId(file.getMimetype(), file.getFileName())
+            );
+        }
+        return vi;
+    }
+
+
+}