Эх сурвалжийг харах

Fixed: problems in handling a file that is still uploading but in the files list because a synchronization was triggered and finished; problems in UI refresh after removing or renaming a file, while in double pane mode

David A. Velasco 12 жил өмнө
parent
commit
275eb1f8f8

+ 1 - 1
AndroidManifest.xml

@@ -18,7 +18,7 @@
  -->
 <manifest package="eu.alefzero.owncloud"
     android:versionCode="1"
-    android:versionName="0.1.186B" xmlns:android="http://schemas.android.com/apk/res/android">
+    android:versionName="0.1.187B" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />

BIN
res/drawable/uploading_file_indicator.png


+ 8 - 2
res/layout/list_layout.xml

@@ -35,11 +35,17 @@
             android:layout_height="wrap_content"
             android:src="@drawable/local_file_indicator"/>
 
-        <ImageView
+        <!-- ImageView
             android:id="@+id/imageView4"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:src="@drawable/downloading_file_indicator"/>
+            android:src="@drawable/downloading_file_indicator"/ >
+
+        <ImageView
+            android:id="@+id/imageView5"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/uploading_file_indicator"/ -->
 
         <ImageView
             android:id="@+id/imageView1"

+ 4 - 3
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java

@@ -111,11 +111,12 @@ public class FileDataStorageManager implements DataStorageManager {
         cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
 
         if (fileExists(file.getRemotePath())) {
-            OCFile tmpfile = getFileByPath(file.getRemotePath());
-            file.setStoragePath(tmpfile.getStoragePath());
+            OCFile oldFile = getFileByPath(file.getRemotePath());
+            if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+                file.setStoragePath(oldFile.getStoragePath());
             if (!file.isDirectory());
                 cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-            file.setFileId(tmpfile.getFileId());
+            file.setFileId(oldFile.getFileId());
 
             overriden = true;
             if (getContentResolver() != null) {

+ 22 - 18
src/eu/alefzero/owncloud/files/services/FileDownloader.java

@@ -35,7 +35,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     public static final String EXTRA_FILE_PATH = "FILE_PATH";
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
     public static final String EXTRA_FILE_SIZE = "FILE_SIZE";
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";    
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+    
     private static final String TAG = "FileDownloader";
 
     private NotificationManager mNotificationMngr;
@@ -172,26 +173,29 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         tmpFile.getParentFile().mkdirs();
         mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());
         File newFile = null;
-        if (wdc.downloadFile(mRemotePath, tmpFile)) {
-            newFile = new File(getSavePath() + mAccount.name + mFilePath);
-            newFile.getParentFile().mkdirs();
-            boolean moved = tmpFile.renameTo(newFile);
+        try {
+            if (wdc.downloadFile(mRemotePath, tmpFile)) {
+                newFile = new File(getSavePath() + mAccount.name + mFilePath);
+                newFile.getParentFile().mkdirs();
+                boolean moved = tmpFile.renameTo(newFile);
             
-            if (moved) {
-                ContentValues cv = new ContentValues();
-                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());
-                getContentResolver().update(
-                    ProviderTableMeta.CONTENT_URI,
-                    cv,
-                    ProviderTableMeta.FILE_NAME + "=? AND "
-                            + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                    new String[] {
-                            mFilePath.substring(mFilePath.lastIndexOf('/') + 1),
-                            mAccount.name });
-                downloadResult = true;
+                if (moved) {
+                    ContentValues cv = new ContentValues();
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());
+                    getContentResolver().update(
+                            ProviderTableMeta.CONTENT_URI,
+                            cv,
+                            ProviderTableMeta.FILE_NAME + "=? AND "
+                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                            new String[] {
+                                mFilePath.substring(mFilePath.lastIndexOf('/') + 1),
+                                mAccount.name });
+                    downloadResult = true;
+                }
             }
+        } finally {
+            mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));
         }
-        mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));
 
         
         /// notify result

+ 33 - 18
src/eu/alefzero/owncloud/files/services/FileUploader.java

@@ -30,6 +30,9 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID";
+    public static final String EXTRA_UPLOAD_RESULT = "RESULT";
+    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
+    public static final String EXTRA_FILE_PATH = "FILE_PATH";
     
     public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
     public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
@@ -184,29 +187,41 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             if (mimeType == null)
                 mimeType = "application/octet-stream";
             mCurrentIndexUpload = i;
-            mRemotePaths[i] = getAvailableRemotePath(wc, mRemotePaths[i]);
-            mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
             long parentDirId = -1;
-            if (mRemotePaths[i] != null && wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
-                mSuccessCounter++;
-                OCFile new_file = new OCFile(mRemotePaths[i]);
-                new_file.setMimetype(mimeType);
-                new_file.setFileLength(localFiles[i].length());
-                new_file.setModificationTimestamp(System.currentTimeMillis());
-                new_file.setLastSyncDate(0);
-                new_file.setStoragePath(mLocalPaths[i]);         
+            boolean uploadResult = false;
+            String availablePath = getAvailableRemotePath(wc, mRemotePaths[i]);
+            try {
                 File f = new File(mRemotePaths[i]);
                 parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId();
-                new_file.setParentId(parentDirId);
-                storageManager.saveFile(new_file);
+                if(availablePath != null) {
+                    mRemotePaths[i] = availablePath;
+                    mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
+                    if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
+                        OCFile new_file = new OCFile(mRemotePaths[i]);
+                        new_file.setMimetype(mimeType);
+                        new_file.setFileLength(localFiles[i].length());
+                        new_file.setModificationTimestamp(System.currentTimeMillis());
+                        new_file.setLastSyncDate(0);
+                        new_file.setStoragePath(mLocalPaths[i]);         
+                        new_file.setParentId(parentDirId);
+                        storageManager.saveFile(new_file);
+                        mSuccessCounter++;
+                        uploadResult = true;
+                    }
+                }
+            } finally {
+                mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
+                
+                /// notify upload (or fail) of EACH file to activities interested
+                Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
+                end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
+                end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult);
+                end.putExtra(EXTRA_REMOTE_PATH, mRemotePaths[i]);
+                end.putExtra(EXTRA_FILE_PATH, mLocalPaths[i]);
+                end.putExtra(ACCOUNT_NAME, mAccount.name);
+                sendBroadcast(end);
             }
-            mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
             
-            /// notify upload of EACH file to activities interested
-            Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
-            end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
-            end.putExtra(ACCOUNT_NAME, mAccount.name);
-            sendBroadcast(end);
         }
         
         /// notify final result

+ 11 - 1
src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java

@@ -32,6 +32,7 @@ import eu.alefzero.owncloud.R;
 import eu.alefzero.owncloud.datamodel.OCFile;
 import eu.alefzero.owncloud.files.services.FileDownloader;
 import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;
+import eu.alefzero.owncloud.ui.fragment.FileListFragment;
 
 /**
  * This activity displays the details of a file like its name, its size and so
@@ -40,7 +41,7 @@ import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;
  * @author Bartek Przybylski
  * 
  */
-public class FileDetailActivity extends SherlockFragmentActivity {
+public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {
     
     private boolean mConfigurationChangedToLandscape = false;
 
@@ -108,5 +109,14 @@ public class FileDetailActivity extends SherlockFragmentActivity {
         startActivity(intent);
         finish();
     }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFileStateChanged() {
+        // nothing to do here!
+    }
+    
 
 }

+ 14 - 1
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java

@@ -80,7 +80,7 @@ import eu.alefzero.webdav.WebdavClient;
  */
 
 public class FileDisplayActivity extends SherlockFragmentActivity implements
-    FileListFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener  {
+    FileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener  {
     
     private ArrayAdapter<String> mDirectories;
     private OCFile mCurrentDir;
@@ -788,6 +788,19 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
         }
     }
     
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFileStateChanged() {
+        FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+        if (fileListFragment != null) { 
+            fileListFragment.listDirectory();
+        }
+    }
+    
+    
     /**
      *  Operations in this method should be preferably performed in onCreate to have a lighter onResume method. 
      * 

+ 28 - 5
src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java

@@ -25,6 +25,7 @@ import eu.alefzero.owncloud.R;
 import eu.alefzero.owncloud.datamodel.DataStorageManager;
 import eu.alefzero.owncloud.datamodel.OCFile;
 import eu.alefzero.owncloud.files.services.FileDownloader;
+import eu.alefzero.owncloud.files.services.FileUploader;
 
 import android.accounts.Account;
 import android.content.Context;
@@ -114,18 +115,40 @@ public class FileListListAdapter implements ListAdapter {
             } else {
                 fileIcon.setImageResource(R.drawable.ic_menu_archive);
             }
-            ImageView downloaded = (ImageView) view.findViewById(R.id.imageView2);
+            ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);
+            if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
+                localStateView.setImageResource(R.drawable.downloading_file_indicator);
+                localStateView.setVisibility(View.VISIBLE);
+            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
+                localStateView.setImageResource(R.drawable.uploading_file_indicator);
+                localStateView.setVisibility(View.VISIBLE);
+            } else if (file.isDown()) {
+                localStateView.setImageResource(R.drawable.local_file_indicator);
+                localStateView.setVisibility(View.VISIBLE);
+            } else {
+                localStateView.setVisibility(View.INVISIBLE);
+            }
+                /*
+            ImageView down = (ImageView) view.findViewById(R.id.imageView2);
             ImageView downloading = (ImageView) view.findViewById(R.id.imageView4);
+            ImageView uploading = (ImageView) view.findViewById(R.id.imageView5);
             if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {
-                downloaded.setVisibility(View.INVISIBLE);
+                down.setVisibility(View.INVISIBLE);
                 downloading.setVisibility(View.VISIBLE);
+                uploading.setVisibility(View.INVISIBLE);
+            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {
+                down.setVisibility(View.INVISIBLE);
+                downloading.setVisibility(View.INVISIBLE);
+                uploading.setVisibility(View.VISIBLE);
             } else if (file.isDown()) {
-                 downloaded.setVisibility(View.VISIBLE);
+                 down.setVisibility(View.VISIBLE);
                  downloading.setVisibility(View.INVISIBLE);
+                 uploading.setVisibility(View.INVISIBLE);
             } else {
-                downloaded.setVisibility(View.INVISIBLE);
+                down.setVisibility(View.INVISIBLE);
                 downloading.setVisibility(View.INVISIBLE);
-            }
+                uploading.setVisibility(View.INVISIBLE);
+            }*/
                 
             if (!file.isDirectory()) {
                 view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);

+ 104 - 11
src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java

@@ -40,6 +40,8 @@ import org.json.JSONObject;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
+import android.annotation.SuppressLint;
+import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -97,6 +99,8 @@ public class FileDetailFragment extends SherlockFragment implements
     public static final String EXTRA_FILE = "FILE";
     public static final String EXTRA_ACCOUNT = "ACCOUNT";
 
+    private FileDetailFragment.ContainerActivity mContainerActivity;
+    
     private int mLayout;
     private View mView;
     private OCFile mFile;
@@ -104,6 +108,7 @@ public class FileDetailFragment extends SherlockFragment implements
     private ImageView mPreview;
     
     private DownloadFinishReceiver mDownloadFinishReceiver;
+    private UploadFinishReceiver mUploadFinishReceiver;
 
     private static final String TAG = "FileDetailFragment";
     public static final String FTAG = "FileDetails"; 
@@ -140,6 +145,20 @@ public class FileDetailFragment extends SherlockFragment implements
         }
     }
     
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        try {
+            mContainerActivity = (ContainerActivity) activity;
+        } catch (ClassCastException e) {
+            throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");
+        }
+    }
+    
     
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -183,18 +202,29 @@ public class FileDetailFragment extends SherlockFragment implements
     @Override
     public void onResume() {
         super.onResume();
+        
         mDownloadFinishReceiver = new DownloadFinishReceiver();
         IntentFilter filter = new IntentFilter(
                 FileDownloader.DOWNLOAD_FINISH_MESSAGE);
         getActivity().registerReceiver(mDownloadFinishReceiver, filter);
+        
+        mUploadFinishReceiver = new UploadFinishReceiver();
+        filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+        getActivity().registerReceiver(mUploadFinishReceiver, filter);
+        
         mPreview = (ImageView)mView.findViewById(R.id.fdPreview);
     }
 
     @Override
     public void onPause() {
         super.onPause();
+        
         getActivity().unregisterReceiver(mDownloadFinishReceiver);
         mDownloadFinishReceiver = null;
+        
+        getActivity().unregisterReceiver(mUploadFinishReceiver);
+        mUploadFinishReceiver = null;
+        
         if (mPreview != null) {
             mPreview = null;
         }
@@ -218,9 +248,10 @@ public class FileDetailFragment extends SherlockFragment implements
                 i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());
                 
                 // update ui 
-                setButtonsForDownloading();
+                setButtonsForTransferring();
                 
                 getActivity().startService(i);
+                mContainerActivity.onFileStateChanged();    // this is not working; it is performed before the fileDownloadService registers it as 'in progress'
                 break;
             }
             case R.id.fdKeepInSync: {
@@ -230,6 +261,8 @@ public class FileDetailFragment extends SherlockFragment implements
                 fdsm.saveFile(mFile);
                 if (mFile.keepInSync()) {
                     onClick(getView().findViewById(R.id.fdDownloadBtn));
+                } else {    
+                    mContainerActivity.onFileStateChanged();    // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)
                 }
                 break;
             }
@@ -361,8 +394,8 @@ public class FileDetailFragment extends SherlockFragment implements
             cb.setChecked(mFile.keepInSync());
 
             // configure UI for depending upon local state of the file
-            if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath())) {
-                setButtonsForDownloading();
+            if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {
+                setButtonsForTransferring();
                 
             } else if (mFile.isDown()) {
                 // Update preview
@@ -483,10 +516,10 @@ public class FileDetailFragment extends SherlockFragment implements
     /**
      * Enables or disables buttons for a file being downloaded
      */
-    private void setButtonsForDownloading() {
+    private void setButtonsForTransferring() {
         if (!isEmpty()) {
             Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
-            downloadButton.setText(R.string.filedetails_download_in_progress);
+            //downloadButton.setText(R.string.filedetails_download_in_progress);    // ugly
             downloadButton.setEnabled(false);   // TODO replace it with a 'cancel download' button
         
             // let's protect the user from himself ;)
@@ -502,7 +535,7 @@ public class FileDetailFragment extends SherlockFragment implements
     private void setButtonsForDown() {
         if (!isEmpty()) {
             Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
-            downloadButton.setText(R.string.filedetails_redownload);
+            //downloadButton.setText(R.string.filedetails_redownload);      // ugly
             downloadButton.setEnabled(true);
         
             ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true);
@@ -517,7 +550,7 @@ public class FileDetailFragment extends SherlockFragment implements
     private void setButtonsForRemote() {
         if (!isEmpty()) {
             Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
-            downloadButton.setText(R.string.filedetails_download);
+            //downloadButton.setText(R.string.filedetails_download);    // unnecessary
             downloadButton.setEnabled(true);
             
             ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);
@@ -545,6 +578,31 @@ public class FileDetailFragment extends SherlockFragment implements
         }*/
         return false;
     }
+    
+    
+    /**
+     * Interface to implement by any Activity that includes some instance of FileDetailFragment
+     * 
+     * @author David A. Velasco
+     */
+    public interface ContainerActivity {
+
+        /**
+         * Callback method invoked when the detail fragment wants to notice its container 
+         * activity about a relevant state the file shown by the fragment.
+         * 
+         * Added to notify to FileDisplayActivity about the need of refresh the files list. 
+         * 
+         * Currently called when:
+         *  - a download is started;
+         *  - a rename is completed;
+         *  - a deletion is completed;
+         *  - the 'inSync' flag is changed;
+         */
+        public void onFileStateChanged();
+        
+    }
+    
 
     /**
      * Once the file download has finished -> update view
@@ -560,7 +618,7 @@ public class FileDetailFragment extends SherlockFragment implements
                 String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
                 if (mFile.getRemotePath().equals(downloadedRemotePath)) {
                     if (downloadWasFine) {
-                        mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH));
+                        mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH));    // updates the local object without accessing the database again
                     }
                     updateFileDetails();    // it updates the buttons; must be called although !downloadWasFine
                 }
@@ -568,6 +626,37 @@ public class FileDetailFragment extends SherlockFragment implements
         }
     }
     
+    
+    /**
+     * Once the file upload has finished -> update view
+     * 
+     * Being notified about the finish of an upload is necessary for the next sequence:
+     *   1. Upload a big file.
+     *   2. Force a synchronization; if it finished before the upload, the file in transfer will be included in the local database and in the file list
+     *      of its containing folder; the the server includes it in the PROPFIND requests although it's not fully upload. 
+     *   3. Click the file in the list to see its details.
+     *   4. Wait for the upload finishes; at this moment, the details view must be refreshed to enable the action buttons.
+     */
+    private class UploadFinishReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
+
+            if (!isEmpty() && accountName.equals(mAccount.name)) {
+                boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
+                String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);
+                if (mFile.getRemotePath().equals(uploadRemotePath)) {
+                    if (uploadWasFine) {
+                        FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
+                        mFile = fdsm.getFileByPath(mFile.getRemotePath());
+                    }
+                    updateFileDetails();    // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server
+                }
+            }
+        }
+    }
+    
+
     // this is a temporary class for sharing purposes, it need to be replaced in transfer service
     private class ShareRunnable implements Runnable {
         private String mPath;
@@ -753,7 +842,10 @@ public class FileDetailFragment extends SherlockFragment implements
                     mFile = mNew;
                     mHandler.post(new Runnable() {
                         @Override
-                        public void run() { updateFileDetails(mFile, mAccount); }
+                        public void run() { 
+                            updateFileDetails(mFile, mAccount);
+                            mContainerActivity.onFileStateChanged();
+                        }
                     });
                 }
                 Log.e("ASD", ""+move.getQueryString());
@@ -890,6 +982,7 @@ public class FileDetailFragment extends SherlockFragment implements
                                     FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
                                     transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
                                     transaction.commit();
+                                    mContainerActivity.onFileStateChanged();
                                     
                                 } else {
                                     getActivity().finish();
@@ -932,7 +1025,8 @@ public class FileDetailFragment extends SherlockFragment implements
     }
     
     class BitmapLoader extends AsyncTask<String, Void, Bitmap> {
-        @Override
+        @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20
+		@Override
         protected Bitmap doInBackground(String... params) {
             Bitmap result = null;
             if (params.length != 1) return result;
@@ -956,7 +1050,6 @@ public class FileDetailFragment extends SherlockFragment implements
                 int width = options.outWidth;
                 int height = options.outHeight;
                 int scale = 1;
-                boolean recycle = false;
                 if (width >= 2048 || height >= 2048) {
                     scale = (int) Math.ceil((Math.ceil(Math.max(height, width) / 2048.)));
                     options.inSampleSize = scale;