From: David A. Velasco Date: Wed, 27 Feb 2013 13:08:58 +0000 (+0100) Subject: Gallery handles multiple downloads gracefully X-Git-Tag: oc-android-1.4.3~39^2~34 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/86cec34b2534b770d9e07700c6b64ebea1c1296f Gallery handles multiple downloads gracefully --- diff --git a/src/com/owncloud/android/ui/preview/FileDownloadFragment.java b/src/com/owncloud/android/ui/preview/FileDownloadFragment.java index da43d119..63e8ade8 100644 --- a/src/com/owncloud/android/ui/preview/FileDownloadFragment.java +++ b/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) { diff --git a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java index 3bff9a12..f797580d 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/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); + } + + } + + } diff --git a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java index da700377..87b35206 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/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"); diff --git a/src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java b/src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java index 16d880f3..9c56263b 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java +++ b/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 mImageFiles; private Account mAccount; private Set mObsoleteFragments; + private Set mObsoletePositions; private DataStorageManager mStorageManager; - /* private final FragmentManager mFragmentManager; private FragmentTransaction mCurTransaction = null; private ArrayList mSavedState = new ArrayList(); private ArrayList mFragments = new ArrayList(); 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(); + mObsoletePositions = new HashSet(); + 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 { } } } - } */ + } }