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

Gallery handles multiple downloads gracefully

David A. Velasco 12 жил өмнө
parent
commit
86cec34b25

+ 13 - 40
src/com/owncloud/android/ui/preview/FileDownloadFragment.java

@@ -22,11 +22,8 @@ import java.lang.ref.WeakReference;
 
 import android.accounts.Account;
 import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.Bundle;
+import android.support.v4.app.FragmentStatePagerAdapter;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -39,7 +36,6 @@ import android.widget.TextView;
 import com.actionbarsherlock.app.SherlockFragment;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.ui.fragment.FileFragment;
 
@@ -64,13 +60,14 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
     private Account mAccount;
     private FileDataStorageManager mStorageManager;
     
-    private DownloadFinishReceiver mDownloadFinishReceiver;
     public ProgressListener mProgressListener;
     private boolean mListening;
     
     private static final String TAG = FileDownloadFragment.class.getSimpleName();
 
+    private boolean mIgnoreFirstSavedState;
     
+
     /**
      * Creates an empty details fragment.
      * 
@@ -82,6 +79,7 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
         mStorageManager = null;
         mProgressListener = null;
         mListening = false;
+        mIgnoreFirstSavedState = false;
     }
     
     
@@ -92,13 +90,15 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
      * 
      * @param fileToDetail      An {@link OCFile} to show in the fragment
      * @param ocAccount         An ownCloud account; needed to start downloads
+     * @param ignoreFirstSavedState     Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter}; TODO better solution 
      */
-    public FileDownloadFragment(OCFile fileToDetail, Account ocAccount) {
+    public FileDownloadFragment(OCFile fileToDetail, Account ocAccount, boolean ignoreFirstSavedState) {
         mFile = fileToDetail;
         mAccount = ocAccount;
         mStorageManager = null; // we need a context to init this; the container activity is not available yet at this moment 
         mProgressListener = null;
         mListening = false;
+        mIgnoreFirstSavedState = ignoreFirstSavedState;
     }
     
     
@@ -115,8 +115,12 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
         super.onCreateView(inflater, container, savedInstanceState);
         
         if (savedInstanceState != null) {
-            mFile = savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_FILE);
-            mAccount = savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_ACCOUNT);
+            if (!mIgnoreFirstSavedState) {
+                mFile = savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_FILE);
+                mAccount = savedInstanceState.getParcelable(FileDownloadFragment.EXTRA_ACCOUNT);
+            } else {
+                mIgnoreFirstSavedState = false;
+            }
         }
         
         View view = null;
@@ -179,11 +183,6 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
     public void onResume() {
         Log.e(TAG, "PREVIEW_DOWNLOAD_FRAGMENT ONRESUME " + mFile.getFileName());
         super.onResume();
-        
-        mDownloadFinishReceiver = new DownloadFinishReceiver();
-        IntentFilter filter = new IntentFilter(
-                FileDownloader.DOWNLOAD_FINISH_MESSAGE);
-        getActivity().registerReceiver(mDownloadFinishReceiver, filter);
     }
 
 
@@ -191,9 +190,6 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
     public void onPause() {
         super.onPause();
         Log.e(TAG, "PREVIEW_DOWNLOAD_FRAGMENT ONPAUSE " + mFile.getFileName());
-        
-        getActivity().unregisterReceiver(mDownloadFinishReceiver);
-        mDownloadFinishReceiver = null;
     }
 
     
@@ -323,29 +319,6 @@ public class FileDownloadFragment extends SherlockFragment implements OnClickLis
     }
     
 
-    /**
-     * Once the file download has finished -> update view
-     */
-    private class DownloadFinishReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
-            if (accountName.equals(mAccount.name)) {
-                boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
-                String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
-                if (mFile.getRemotePath().equals(downloadedRemotePath)) {
-                    if (downloadWasFine) {
-                        mFile = mStorageManager.getFileByPath(downloadedRemotePath);
-                    }
-                    updateView(false);
-                    getActivity().removeStickyBroadcast(intent);
-                    mContainerActivity.notifySuccessfulDownload(mFile, intent, downloadWasFine);
-                }
-            }
-        }
-    }
-    
-    
     public void listenForTransferProgress() {
         if (mProgressListener != null && !mListening) {
             if (mContainerActivity.getFileDownloaderBinder() != null) {

+ 102 - 23
src/com/owncloud/android/ui/preview/PreviewImageActivity.java

@@ -20,9 +20,11 @@ package com.owncloud.android.ui.preview;
 import android.accounts.Account;
 import android.app.Dialog;
 import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -71,10 +73,11 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
     private FileDownloaderBinder mDownloaderBinder = null;
     private ServiceConnection mDownloadConnection, mUploadConnection = null;
     private FileUploaderBinder mUploaderBinder = null;
-    private OCFile mWaitingToPreview = null;
 
     private boolean mRequestWaitingForBinder;
     
+    private DownloadFinishReceiver mDownloadFinishReceiver;
+    
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -106,10 +109,8 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
         }
 
         if (savedInstanceState != null) {
-            mWaitingToPreview = (OCFile) savedInstanceState.getParcelable(KEY_WAITING_TO_PREVIEW);
             mRequestWaitingForBinder = savedInstanceState.getBoolean(KEY_WAITING_FOR_BINDER);
         } else {
-            mWaitingToPreview = null;
             mRequestWaitingForBinder = false;
         }
         
@@ -127,22 +128,26 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
         mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
         int position = mPreviewImagePagerAdapter.getFilePosition(mFile);
         position = (position >= 0) ? position : 0;
-        mViewPager.setAdapter(mPreviewImagePagerAdapter);        
+        mViewPager.setAdapter(mPreviewImagePagerAdapter); 
         mViewPager.setOnPageChangeListener(this);
         Log.e(TAG, "Setting initial position " + position);
         mViewPager.setCurrentItem(position);
         if (position == 0 && !mFile.isDown()) {
             // this is necessary because mViewPager.setCurrentItem(0) just after setting the adapter does not result in a call to #onPageSelected(0) 
-            mWaitingToPreview = mFile; 
             mRequestWaitingForBinder = true;
         }
     }
     
-
+    
+    @Override
+    public void onStart() {
+        super.onStart();
+        Log.e(TAG, "PREVIEW ACTIVITY ON START");
+    }
+    
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putParcelable(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
         outState.putBoolean(KEY_WAITING_FOR_BINDER, mRequestWaitingForBinder);    
     }
 
@@ -157,10 +162,9 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
                 Log.e(TAG, "PREVIEW_IMAGE Download service connected");
                 mDownloaderBinder = (FileDownloaderBinder) service;
                 if (mRequestWaitingForBinder) {
-                   if (mWaitingToPreview != null) {
-                       requestForDownload();
-                   }
-                   mRequestWaitingForBinder = false;
+                    mRequestWaitingForBinder = false;
+                    Log.e(TAG, "Simulating reselection of current page after connection of download binder");
+                    onPageSelected(mViewPager.getCurrentItem());
                 }
                     
             } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
@@ -219,6 +223,24 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
     @Override
     protected void onResume() {
         super.onResume();
+        Log.e(TAG, "PREVIEW ACTIVITY ONRESUME");
+        mDownloadFinishReceiver = new DownloadFinishReceiver();
+        IntentFilter filter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
+        registerReceiver(mDownloadFinishReceiver, filter);
+    }
+
+    
+    @Override
+    protected void onPostResume() {
+        super.onPostResume();
+        Log.e(TAG, "PREVIEW ACTIVITY ONPOSTRESUME");
+    }
+    
+    @Override
+    public void onPause() {
+        super.onPause();
+        unregisterReceiver(mDownloadFinishReceiver);
+        mDownloadFinishReceiver = null;
     }
     
 
@@ -288,22 +310,22 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
     }
 
     
-    private void requestForDownload() {
-        Log.e(TAG, "REQUEST FOR DOWNLOAD : " + mWaitingToPreview.getFileName());
+    private void requestForDownload(OCFile file) {
+        Log.e(TAG, "REQUEST FOR DOWNLOAD : " + file.getFileName());
         if (mDownloaderBinder == null) {
-            mRequestWaitingForBinder = true;
+            Log.e(TAG, "requestForDownload called without binder to download service");
             
-        } else if (!mDownloaderBinder.isDownloading(mAccount, mWaitingToPreview)) {
+        } else if (!mDownloaderBinder.isDownloading(mAccount, file)) {
             Intent i = new Intent(this, FileDownloader.class);
             i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
-            i.putExtra(FileDownloader.EXTRA_FILE, mWaitingToPreview);
+            i.putExtra(FileDownloader.EXTRA_FILE, file);
             startService(i);
         }
-        mViewPager.invalidate();
     }
 
     @Override
     public void notifySuccessfulDownload(OCFile file, Intent intent, boolean success) {
+        /*
         if (success) {
             if (mWaitingToPreview != null && mWaitingToPreview.equals(file)) {
                 mWaitingToPreview = null;
@@ -314,6 +336,7 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
                 Log.e(TAG, "AFTER NOTIFY DATA SET CHANGED");
             }
         }
+        */
     }
 
     
@@ -325,13 +348,16 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
     @Override
     public void onPageSelected(int position) {
         Log.e(TAG, "onPageSelected " + position);
-        OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); 
-        getSupportActionBar().setTitle(currentFile.getFileName());
-        if (currentFile.isDown()) {
-            mWaitingToPreview = null;
+        if (mDownloaderBinder == null) {
+            mRequestWaitingForBinder = true;
+            
         } else {
-            mWaitingToPreview = currentFile;
-            requestForDownload();
+            OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); 
+            getSupportActionBar().setTitle(currentFile.getFileName());
+            if (!currentFile.isDown()) {
+                requestForDownload(currentFile);
+                //updateCurrentDownloadFragment(true);        
+            }
         }
     }
     
@@ -359,4 +385,57 @@ public class PreviewImageActivity extends SherlockFragmentActivity implements Fi
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
     }
     
+
+    private void updateCurrentDownloadFragment(boolean transferring) {
+        FileFragment fragment = mPreviewImagePagerAdapter.getFragmentAt(mViewPager.getCurrentItem());
+        if (fragment instanceof FileDownloadFragment) {
+            ((FileDownloadFragment) fragment).updateView(transferring); 
+            //mViewPager.invalidate();
+        }
+    }
+    
+    
+    /**
+     * Class waiting for broadcast events from the {@link FielDownloader} service.
+     * 
+     * Updates the UI when a download is started or finished, provided that it is relevant for the
+     * folder displayed in the gallery.
+     */
+    private class DownloadFinishReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
+            String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+            if (mAccount.name.equals(accountName) && 
+                    downloadedRemotePath != null) {
+
+                OCFile file = mStorageManager.getFileByPath(downloadedRemotePath);
+                int position = mPreviewImagePagerAdapter.getFilePosition(file);
+                boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
+                boolean isCurrent =  (mViewPager.getCurrentItem() == position);
+                
+                if (position >= 0) {
+                    /// ITS MY BUSSINESS
+                    Log.e(TAG, "downloaded file FOUND in adapter");
+                    if (downloadWasFine) {
+                        mPreviewImagePagerAdapter.updateFile(position, file);
+                        //Log.e(TAG, "BEFORE NOTIFY DATA SET CHANGED");
+                        mPreviewImagePagerAdapter.notifyDataSetChanged();
+                        //Log.e(TAG, "AFTER NOTIFY DATA SET CHANGED");
+                        
+                    } else if (isCurrent) {
+                        updateCurrentDownloadFragment(false);
+                    }
+                    
+                } else {
+                    Log.e(TAG, "DOWNLOADED FILE NOT FOUND IN ADAPTER ");
+                }
+                
+            }
+            removeStickyBroadcast(intent);
+        }
+
+    }
+    
+    
 }

+ 15 - 7
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@ -36,6 +36,7 @@ import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
+import android.support.v4.app.FragmentStatePagerAdapter;
 import android.util.Log;
 import android.view.Display;
 import android.view.LayoutInflater;
@@ -91,19 +92,22 @@ public class PreviewImageFragment extends SherlockFragment implements   FileFrag
     
     private static final String TAG = PreviewImageFragment.class.getSimpleName();
 
+    private boolean mIgnoreFirstSavedState;
     
     /**
      * Creates a fragment to preview an image.
      * 
      * When 'imageFile' or 'ocAccount' are null
      * 
-     * @param imageFile         An {@link OCFile} to preview as an image in the fragment
-     * @param ocAccount         An ownCloud account; needed to start downloads
+     * @param imageFile                 An {@link OCFile} to preview as an image in the fragment
+     * @param ocAccount                 An ownCloud account; needed to start downloads
+     * @param ignoreFirstSavedState     Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter}; TODO better solution 
      */
-    public PreviewImageFragment(OCFile fileToDetail, Account ocAccount) {
+    public PreviewImageFragment(OCFile fileToDetail, Account ocAccount, boolean ignoreFirstSavedState) {
         mFile = fileToDetail;
         mAccount = ocAccount;
-        mStorageManager = null; // we need a context to init this; the container activity is not available yet at this moment 
+        mStorageManager = null; // we need a context to init this; the container activity is not available yet at this moment
+        mIgnoreFirstSavedState = ignoreFirstSavedState;
     }
     
     
@@ -118,6 +122,7 @@ public class PreviewImageFragment extends SherlockFragment implements   FileFrag
         mFile = null;
         mAccount = null;
         mStorageManager = null;
+        mIgnoreFirstSavedState = false;
     }
     
     
@@ -165,9 +170,12 @@ public class PreviewImageFragment extends SherlockFragment implements   FileFrag
         super.onActivityCreated(savedInstanceState);
         mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
         if (savedInstanceState != null) {
-            mFile = savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_FILE);
-            mAccount = savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_ACCOUNT);
-            
+            if (!mIgnoreFirstSavedState) {
+                mFile = savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_FILE);
+                mAccount = savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_ACCOUNT);
+            } else {
+                mIgnoreFirstSavedState = false;
+            }
         }
         if (mFile == null) {
             throw new IllegalStateException("Instanced with a NULL OCFile");

+ 32 - 13
src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java

@@ -36,29 +36,29 @@ import android.view.ViewGroup;
 
 import com.owncloud.android.datamodel.DataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.fragment.FileFragment;
 
 /**
  * Adapter class that provides Fragment instances  
  * 
  * @author David A. Velasco
  */
-//public class PreviewImagePagerAdapter extends PagerAdapter {
-public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
+public class PreviewImagePagerAdapter extends PagerAdapter {
+//public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
     
     private static final String TAG = PreviewImagePagerAdapter.class.getSimpleName();
             
     private Vector<OCFile> mImageFiles;
     private Account mAccount;
     private Set<Object> mObsoleteFragments;
+    private Set<Integer> mObsoletePositions;
     private DataStorageManager mStorageManager;
     
-    /*
     private final FragmentManager mFragmentManager;
     private FragmentTransaction mCurTransaction = null;
     private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
     private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
     private Fragment mCurrentPrimaryItem = null;
-    */
 
     /**
      * Constructor.
@@ -68,8 +68,8 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
      * @param storageManager    Bridge to database.
      */
     public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder, Account account, DataStorageManager storageManager) {
-        super(fragmentManager);
-
+        //super(fragmentManager);
+        
         if (fragmentManager == null) {
             throw new IllegalArgumentException("NULL FragmentManager instance");
         }
@@ -84,6 +84,8 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
         mStorageManager = storageManager;
         mImageFiles = mStorageManager.getDirectoryImages(parentFolder); 
         mObsoleteFragments = new HashSet<Object>();
+        mObsoletePositions = new HashSet<Integer>();
+        mFragmentManager = fragmentManager;
     }
 
     
@@ -102,9 +104,9 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
         OCFile file = mImageFiles.get(i);
         Fragment fragment = null;
         if (file.isDown()) {
-            fragment = new PreviewImageFragment(file, mAccount);
+            fragment = new PreviewImageFragment(file, mAccount, mObsoletePositions.contains(Integer.valueOf(i)));
         } else {
-            fragment = new FileDownloadFragment(file, mAccount);
+            fragment = new FileDownloadFragment(file, mAccount, mObsoletePositions.contains(Integer.valueOf(i)));
         }
         return fragment;
     }
@@ -124,8 +126,9 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
     }
 
     public void updateFile(int position, OCFile file) {
-        mImageFiles.set(position, file);
         mObsoleteFragments.add(instantiateItem(null, position));
+        mObsoletePositions.add(Integer.valueOf(position));
+        mImageFiles.set(position, file);
     }
     
     @Override
@@ -139,11 +142,27 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
     }
 
 
-    /* *
+    /**
+     * Should not be used for not already started fragments...
+     *  
+     * @return
+     */
+    protected FileFragment getFragmentAt(int position) {
+        try {
+            return (FileFragment) instantiateItem(null, position);
+            
+        } catch (Exception e) {
+            Log.e(TAG, "Wrong access to fragment in gallery ", e);
+            return null;
+        }
+    }
+
+
+    /**
      * Called when a change in the shown pages is going to start being made.
      * 
      * @param   container   The containing View which is displaying this adapter's page views.
-     * -/
+     */
     @Override
     public void startUpdate(ViewGroup container) {
         Log.e(TAG, "** startUpdate");
@@ -182,7 +201,7 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
         }
         fragment.setMenuVisibility(false);
         mFragments.set(position, fragment);
-        Log.e(TAG, "** \t adding fragment at position " + position + ", containerId " + container.getId());
+        //Log.e(TAG, "** \t adding fragment at position " + position + ", containerId " + container.getId());
         mCurTransaction.add(container.getId(), fragment);
 
         return fragment;
@@ -288,6 +307,6 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
                 }
             }
         }
-    } */
+    }
     
 }