From: Bartek Przybylski Date: Sat, 30 Jun 2012 11:51:31 +0000 (+0200) Subject: Merge branch 'master' of gitorious.org:owncloud/android-devel X-Git-Tag: oc-android-1.4.3~323^2~4^2 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/1e63d71c91c8c4ecf048adc719c7158630d5d063?hp=12c00057e7a4b279ad245d54d906e74a899aec4b Merge branch 'master' of gitorious.org:owncloud/android-devel --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 935a8fc0..bb1f30e6 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -18,7 +18,7 @@ --> + android:versionName="0.1.140B" xmlns:android="http://schemas.android.com/apk/res/android"> diff --git a/res/drawable-hdpi-v9/ic_action_create_dir.png b/res/drawable-hdpi-v9/ic_action_create_dir.png new file mode 100644 index 00000000..ece0eb44 Binary files /dev/null and b/res/drawable-hdpi-v9/ic_action_create_dir.png differ diff --git a/res/drawable-hdpi-v9/ic_action_refresh.png b/res/drawable-hdpi-v9/ic_action_refresh.png new file mode 100644 index 00000000..a7fdc0df Binary files /dev/null and b/res/drawable-hdpi-v9/ic_action_refresh.png differ diff --git a/res/drawable-hdpi-v9/ic_action_search.png b/res/drawable-hdpi-v9/ic_action_search.png new file mode 100644 index 00000000..3549f84d Binary files /dev/null and b/res/drawable-hdpi-v9/ic_action_search.png differ diff --git a/res/drawable-hdpi-v9/ic_action_upload.png b/res/drawable-hdpi-v9/ic_action_upload.png new file mode 100644 index 00000000..2369348c Binary files /dev/null and b/res/drawable-hdpi-v9/ic_action_upload.png differ diff --git a/res/drawable-hdpi/ic_action_create_dir.png b/res/drawable-hdpi/ic_action_create_dir.png index 1d1a03e6..15068bc7 100644 Binary files a/res/drawable-hdpi/ic_action_create_dir.png and b/res/drawable-hdpi/ic_action_create_dir.png differ diff --git a/res/drawable-hdpi/ic_action_create_dir_old.png b/res/drawable-hdpi/ic_action_create_dir_old.png new file mode 100644 index 00000000..49a226e2 Binary files /dev/null and b/res/drawable-hdpi/ic_action_create_dir_old.png differ diff --git a/res/drawable-hdpi/ic_action_refresh.png b/res/drawable-hdpi/ic_action_refresh.png index 479aca46..e6212cf6 100644 Binary files a/res/drawable-hdpi/ic_action_refresh.png and b/res/drawable-hdpi/ic_action_refresh.png differ diff --git a/res/drawable-hdpi/ic_action_refresh_black.png b/res/drawable-hdpi/ic_action_refresh_black.png index 479aca46..e6212cf6 100644 Binary files a/res/drawable-hdpi/ic_action_refresh_black.png and b/res/drawable-hdpi/ic_action_refresh_black.png differ diff --git a/res/drawable-hdpi/ic_action_search.png b/res/drawable-hdpi/ic_action_search.png index f6719d22..f89c4e96 100644 Binary files a/res/drawable-hdpi/ic_action_search.png and b/res/drawable-hdpi/ic_action_search.png differ diff --git a/res/drawable-hdpi/ic_action_upload.png b/res/drawable-hdpi/ic_action_upload.png index d30ee8a8..b372b7e1 100644 Binary files a/res/drawable-hdpi/ic_action_upload.png and b/res/drawable-hdpi/ic_action_upload.png differ diff --git a/res/drawable-ldpi-v9/ic_action_create_dir.png b/res/drawable-ldpi-v9/ic_action_create_dir.png new file mode 100644 index 00000000..8ed2dae9 Binary files /dev/null and b/res/drawable-ldpi-v9/ic_action_create_dir.png differ diff --git a/res/drawable-ldpi-v9/ic_action_refresh.png b/res/drawable-ldpi-v9/ic_action_refresh.png new file mode 100644 index 00000000..bd611e8e Binary files /dev/null and b/res/drawable-ldpi-v9/ic_action_refresh.png differ diff --git a/res/drawable-ldpi-v9/ic_action_search.png b/res/drawable-ldpi-v9/ic_action_search.png new file mode 100644 index 00000000..587d9e0b Binary files /dev/null and b/res/drawable-ldpi-v9/ic_action_search.png differ diff --git a/res/drawable-ldpi-v9/ic_action_upload.png b/res/drawable-ldpi-v9/ic_action_upload.png new file mode 100644 index 00000000..2d4ba56f Binary files /dev/null and b/res/drawable-ldpi-v9/ic_action_upload.png differ diff --git a/res/drawable-ldpi/ic_action_create_dir.png b/res/drawable-ldpi/ic_action_create_dir.png index 49a226e2..78356fe1 100644 Binary files a/res/drawable-ldpi/ic_action_create_dir.png and b/res/drawable-ldpi/ic_action_create_dir.png differ diff --git a/res/drawable-ldpi/ic_action_create_dir_old.png b/res/drawable-ldpi/ic_action_create_dir_old.png new file mode 100644 index 00000000..ce8cdeff Binary files /dev/null and b/res/drawable-ldpi/ic_action_create_dir_old.png differ diff --git a/res/drawable-ldpi/ic_action_refresh.png b/res/drawable-ldpi/ic_action_refresh.png index e6212cf6..63e70e17 100644 Binary files a/res/drawable-ldpi/ic_action_refresh.png and b/res/drawable-ldpi/ic_action_refresh.png differ diff --git a/res/drawable-ldpi/ic_action_refresh_black.png b/res/drawable-ldpi/ic_action_refresh_black.png index e6212cf6..63e70e17 100644 Binary files a/res/drawable-ldpi/ic_action_refresh_black.png and b/res/drawable-ldpi/ic_action_refresh_black.png differ diff --git a/res/drawable-ldpi/ic_action_search.png b/res/drawable-ldpi/ic_action_search.png index f89c4e96..45d2398a 100644 Binary files a/res/drawable-ldpi/ic_action_search.png and b/res/drawable-ldpi/ic_action_search.png differ diff --git a/res/drawable-ldpi/ic_action_upload.png b/res/drawable-ldpi/ic_action_upload.png index b372b7e1..9e3f7450 100644 Binary files a/res/drawable-ldpi/ic_action_upload.png and b/res/drawable-ldpi/ic_action_upload.png differ diff --git a/res/drawable-mdpi-v9/ic_action_create_dir.png b/res/drawable-mdpi-v9/ic_action_create_dir.png new file mode 100644 index 00000000..9215a625 Binary files /dev/null and b/res/drawable-mdpi-v9/ic_action_create_dir.png differ diff --git a/res/drawable-mdpi-v9/ic_action_refresh.png b/res/drawable-mdpi-v9/ic_action_refresh.png new file mode 100644 index 00000000..bb9d855f Binary files /dev/null and b/res/drawable-mdpi-v9/ic_action_refresh.png differ diff --git a/res/drawable-mdpi-v9/ic_action_search.png b/res/drawable-mdpi-v9/ic_action_search.png new file mode 100644 index 00000000..f12e005e Binary files /dev/null and b/res/drawable-mdpi-v9/ic_action_search.png differ diff --git a/res/drawable-mdpi-v9/ic_action_upload.png b/res/drawable-mdpi-v9/ic_action_upload.png new file mode 100644 index 00000000..0faf43b0 Binary files /dev/null and b/res/drawable-mdpi-v9/ic_action_upload.png differ diff --git a/res/drawable-mdpi/ic_action_create_dir.png b/res/drawable-mdpi/ic_action_create_dir.png index ce8cdeff..636cf0ec 100644 Binary files a/res/drawable-mdpi/ic_action_create_dir.png and b/res/drawable-mdpi/ic_action_create_dir.png differ diff --git a/res/drawable-mdpi/ic_action_create_dir_old.png b/res/drawable-mdpi/ic_action_create_dir_old.png new file mode 100644 index 00000000..1d1a03e6 Binary files /dev/null and b/res/drawable-mdpi/ic_action_create_dir_old.png differ diff --git a/res/drawable-mdpi/ic_action_refresh.png b/res/drawable-mdpi/ic_action_refresh.png index 63e70e17..479aca46 100644 Binary files a/res/drawable-mdpi/ic_action_refresh.png and b/res/drawable-mdpi/ic_action_refresh.png differ diff --git a/res/drawable-mdpi/ic_action_refresh_black.png b/res/drawable-mdpi/ic_action_refresh_black.png index 63e70e17..479aca46 100644 Binary files a/res/drawable-mdpi/ic_action_refresh_black.png and b/res/drawable-mdpi/ic_action_refresh_black.png differ diff --git a/res/drawable-mdpi/ic_action_search.png b/res/drawable-mdpi/ic_action_search.png index 45d2398a..f6719d22 100644 Binary files a/res/drawable-mdpi/ic_action_search.png and b/res/drawable-mdpi/ic_action_search.png differ diff --git a/res/drawable-mdpi/ic_action_upload.png b/res/drawable-mdpi/ic_action_upload.png index 9e3f7450..d30ee8a8 100644 Binary files a/res/drawable-mdpi/ic_action_upload.png and b/res/drawable-mdpi/ic_action_upload.png differ diff --git a/res/layout-land/account_setup.xml b/res/layout-land/account_setup.xml index cdd31723..93f3038a 100644 --- a/res/layout-land/account_setup.xml +++ b/res/layout-land/account_setup.xml @@ -42,7 +42,7 @@ android:layout_height="match_parent" android:layout_margin="7dp" android:layout_weight="1" - android:src="@drawable/logo_inverted" /> + android:src="@drawable/owncloud_logo" /> + android:src="@drawable/owncloud_logo" /> Directory name Uploading completed successfully Upload failed: + files uploaded Choose account Contacts Use Secure Connection diff --git a/src/eu/alefzero/owncloud/AccountUtils.java b/src/eu/alefzero/owncloud/AccountUtils.java index 090dec38..d088d2ce 100644 --- a/src/eu/alefzero/owncloud/AccountUtils.java +++ b/src/eu/alefzero/owncloud/AccountUtils.java @@ -68,6 +68,21 @@ public class AccountUtils { return defaultAccount; } + + + /** + * Checks, whether or not there are any ownCloud accounts setup. + * + * @return true, if there is at least one account. + */ + public static boolean accountsAreSetup(Context context) { + AccountManager accMan = AccountManager.get(context); + Account[] accounts = accMan + .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); + return accounts.length > 0; + } + + public static void setCurrentOwnCloudAccount(Context context, String name) { SharedPreferences.Editor appPrefs = PreferenceManager .getDefaultSharedPreferences(context).edit(); diff --git a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java index b6a0a604..93149426 100644 --- a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java +++ b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java @@ -111,9 +111,16 @@ public class PhotoTakenBroadcastReceiver extends BroadcastReceiver { Intent upload_intent = new Intent(context, InstantUploadService.class); Account account = new Account(account_name, AccountAuthenticator.ACCOUNT_TYPE); - String mimeType = MimeTypeMap.getSingleton() - .getMimeTypeFromExtension( - f.getName().substring(f.getName().lastIndexOf('.') + 1)); + String mimeType; + try { + mimeType = MimeTypeMap.getSingleton() + .getMimeTypeFromExtension( + f.getName().substring(f.getName().lastIndexOf('.') + 1)); + + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName()); + mimeType = "application/octet-stream"; + } upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account); upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path); diff --git a/src/eu/alefzero/owncloud/files/services/FileUploader.java b/src/eu/alefzero/owncloud/files/services/FileUploader.java index 5d748c96..23e24c4d 100644 --- a/src/eu/alefzero/owncloud/files/services/FileUploader.java +++ b/src/eu/alefzero/owncloud/files/services/FileUploader.java @@ -1,6 +1,7 @@ package eu.alefzero.owncloud.files.services; import java.io.File; +import java.util.List; import eu.alefzero.owncloud.AccountUtils; import eu.alefzero.owncloud.R; @@ -9,7 +10,6 @@ import eu.alefzero.owncloud.datamodel.FileDataStorageManager; import eu.alefzero.owncloud.datamodel.OCFile; import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener; import eu.alefzero.owncloud.utils.OwnCloudVersion; -import eu.alefzero.webdav.OnUploadProgressListener; import eu.alefzero.webdav.WebdavClient; import android.accounts.Account; import android.accounts.AccountManager; @@ -32,6 +32,9 @@ import android.widget.Toast; public class FileUploader extends Service implements OnDatatransferProgressListener { + public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH"; + public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID"; + public static final String KEY_LOCAL_FILE = "LOCAL_FILE"; public static final String KEY_REMOTE_FILE = "REMOTE_FILE"; public static final String KEY_ACCOUNT = "ACCOUNT"; @@ -47,11 +50,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe private AccountManager mAccountManager; private Account mAccount; private String[] mLocalPaths, mRemotePaths; - private boolean mResult; private int mUploadType; private Notification mNotification; private int mTotalDataToSend, mSendData; private int mCurrentIndexUpload, mPreviousPercent; + private int mSuccessCounter; @Override public IBinder onBind(Intent arg0) { @@ -119,12 +122,16 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } public void run() { - if (mResult) { - Toast.makeText(this, "Upload successfull", Toast.LENGTH_SHORT) - .show(); + String message; + if (mSuccessCounter == mLocalPaths.length) { + message = getString(R.string.uploader_upload_succeed); } else { + message = getString(R.string.uploader_upload_failed); + if (mLocalPaths.length > 1) + message += " (" + mSuccessCounter + " / " + mLocalPaths.length + getString(R.string.uploader_files_uploaded_suffix) + ")"; Toast.makeText(this, "Upload could not be completed", Toast.LENGTH_SHORT).show(); } + Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } public void uploadFile() { @@ -166,15 +173,24 @@ public class FileUploader extends Service implements OnDatatransferProgressListe Log.d(TAG, "Will upload " + mTotalDataToSend + " bytes, with " + mLocalPaths.length + " files"); + mSuccessCounter = 0; + for (int i = 0; i < mLocalPaths.length; ++i) { - String mimeType = MimeTypeMap.getSingleton() - .getMimeTypeFromExtension( - mLocalPaths[i].substring(mLocalPaths[i] + + String mimeType; + try { + mimeType = MimeTypeMap.getSingleton() + .getMimeTypeFromExtension( + mLocalPaths[i].substring(mLocalPaths[i] .lastIndexOf('.') + 1)); - mResult = false; + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mLocalPaths[i]); + mimeType = "application/octet-stream"; + } + mCurrentIndexUpload = i; if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) { - mResult |= true; + mSuccessCounter++; OCFile new_file = new OCFile(mRemotePaths[i]); new_file.setMimetype(mimeType); new_file.setFileLength(new File(mLocalPaths[i]).length()); @@ -182,12 +198,16 @@ public class FileUploader extends Service implements OnDatatransferProgressListe new_file.setLastSyncDate(0); new_file.setStoragePath(mLocalPaths[i]); File f = new File(mRemotePaths[i]); - new_file.setParentId(storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId()); + long parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId(); + new_file.setParentId(parentDirId); storageManager.saveFile(new_file); + + Intent end = new Intent(UPLOAD_FINISH_MESSAGE); + end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId); + sendBroadcast(end); } + } - // notification.contentView.setProgressBar(R.id.status_progress, - // mLocalPaths.length-1, mLocalPaths.length-1, false); mNotificationManager.cancel(42); run(); } diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java index d5512a18..39a88317 100644 --- a/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java +++ b/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java @@ -19,6 +19,9 @@ package eu.alefzero.owncloud.syncadapter; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Vector; import org.apache.jackrabbit.webdav.DavException; @@ -34,6 +37,7 @@ import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; import android.util.Log; +import android.webkit.MimeTypeMap; import eu.alefzero.owncloud.datamodel.FileDataStorageManager; import eu.alefzero.owncloud.datamodel.OCFile; import eu.alefzero.webdav.WebdavEntry; @@ -63,13 +67,10 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { this.setContentProvider(provider); this.setStorageManager(new FileDataStorageManager(account, getContentProvider())); - + Log.d(TAG, "syncing owncloud account " + account.name); - Intent i = new Intent(FileSyncService.SYNC_MESSAGE); - i.putExtra(FileSyncService.IN_PROGRESS, true); - i.putExtra(FileSyncService.ACCOUNT_NAME, account.name); - getContext().sendStickyBroadcast(i); + sendStickyBroadcast(true, -1); // starting message to the main IU PropFindMethod query; try { @@ -98,8 +99,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { syncResult.stats.numIoExceptions++; e.printStackTrace(); } - i.putExtra(FileSyncService.IN_PROGRESS, false); - getContext().sendStickyBroadcast(i); + sendStickyBroadcast(false, -1); } private void fetchData(String uri, SyncResult syncResult, long parentId) { @@ -108,6 +108,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { getClient().executeMethod(query); MultiStatus resp = null; resp = query.getResponseBodyAsMultiStatus(); + List paths = new ArrayList(); + List fileIds = new ArrayList(); for (int i = 1; i < resp.getResponses().length; ++i) { WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath()); OCFile file = fillOCFile(we); @@ -115,15 +117,31 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { getStorageManager().saveFile(file); if (parentId == 0) parentId = file.getFileId(); - if (we.contentType().equals("DIR")) - fetchData(getUri().toString() + we.path(), syncResult, file.getFileId()); + if (we.contentType().equals("DIR")) { + // for recursive fetch later + paths.add(we.path()); + fileIds.add(file.getFileId()); + } } + Vector files = getStorageManager().getDirectoryContent( getStorageManager().getFileById(parentId)); for (OCFile file : files) { if (file.getLastSyncDate() != mCurrentSyncTime && file.getLastSyncDate() != 0) getStorageManager().removeFile(file); } + + // synched folder -> notice to main thread + sendStickyBroadcast(true, parentId); + + // recursive fetch + Iterator pathsIt = paths.iterator(); + Iterator fileIdsIt = fileIds.iterator(); + while (pathsIt.hasNext()) { + fetchData(getUri().toString() + pathsIt.next(), syncResult, fileIdsIt.next()); + } + + } catch (OperationCanceledException e) { e.printStackTrace(); } catch (AuthenticatorException e) { @@ -147,5 +165,16 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { file.setLastSyncDate(mCurrentSyncTime); return file; } + + + private void sendStickyBroadcast(boolean inProgress, long OCDirId) { + Intent i = new Intent(FileSyncService.SYNC_MESSAGE); + i.putExtra(FileSyncService.IN_PROGRESS, inProgress); + i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name); + if (OCDirId > 0) { + i.putExtra(FileSyncService.SYNC_FOLDER, OCDirId); + } + getContext().sendStickyBroadcast(i); + } } diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java index 6ab23db1..6c1ed0fc 100644 --- a/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java +++ b/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java @@ -31,6 +31,7 @@ public class FileSyncService extends Service { public static final String SYNC_MESSAGE = "eu.alefzero.owncloud.files.ACCOUNT_SYNC"; public static final String IN_PROGRESS = "sync_in_progress"; public static final String ACCOUNT_NAME = "account_name"; + public static final String SYNC_FOLDER = "eu.alefzero.owncloud.files.SYNC_FOLDER"; /* * {@inheritDoc} diff --git a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java b/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java index bd0ddb0b..b944240a 100644 --- a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java +++ b/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java @@ -204,8 +204,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity setResult(RESULT_OK, intent); Bundle bundle = new Bundle(); bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); - getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, - bundle); + //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, + // bundle); + ContentResolver.requestSync(account, "org.ownlcoud", bundle); /* * if diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java index f5664ead..00a1f838 100644 --- a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java +++ b/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java @@ -48,7 +48,7 @@ public class FileDetailActivity extends SherlockFragmentActivity { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); mFileDetail = new FileDetailFragment(); - ft.add(R.id.fragment, mFileDetail, "FileDetails"); + ft.replace(R.id.fragment, mFileDetail, "FileDetails"); ft.commit(); } diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java index ec4def42..657d6df9 100644 --- a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java +++ b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java @@ -18,10 +18,7 @@ package eu.alefzero.owncloud.ui.activity; -import java.io.BufferedReader; import java.io.File; -import java.io.InputStreamReader; -import java.lang.Thread.UncaughtExceptionHandler; import java.util.ArrayList; import android.accounts.Account; @@ -37,20 +34,18 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; -import android.telephony.TelephonyManager; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.CheckedTextView; import android.widget.EditText; import android.widget.TextView; +import android.widget.Toast; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar.OnNavigationListener; @@ -67,6 +62,7 @@ import eu.alefzero.owncloud.authenticator.AccountAuthenticator; import eu.alefzero.owncloud.datamodel.DataStorageManager; import eu.alefzero.owncloud.datamodel.FileDataStorageManager; import eu.alefzero.owncloud.datamodel.OCFile; +import eu.alefzero.owncloud.files.services.FileDownloader; import eu.alefzero.owncloud.files.services.FileUploader; import eu.alefzero.owncloud.syncadapter.FileSyncService; import eu.alefzero.owncloud.ui.fragment.FileDetailFragment; @@ -81,16 +77,18 @@ import eu.alefzero.webdav.WebdavClient; */ public class FileDisplayActivity extends SherlockFragmentActivity implements - OnNavigationListener, OnClickListener, android.view.View.OnClickListener { + OnNavigationListener, OnClickListener, android.view.View.OnClickListener { + private ArrayAdapter mDirectories; - private DataStorageManager mStorageManager; - private FileListFragment mFileList; private OCFile mCurrentDir; private String[] mDirs = null; - private SyncBroadcastReceiver syncBroadcastRevceiver; + private DataStorageManager mStorageManager; + private SyncBroadcastReceiver mSyncBroadcastReceiver; + private UploadFinishReceiver mUploadFinishReceiver; private View mLayoutView = null; + private FileListFragment mFileList; private static final String KEY_DIR_ARRAY = "DIR_ARRAY"; private static final String KEY_CURRENT_DIR = "DIR"; @@ -98,39 +96,37 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements private static final int DIALOG_SETUP_ACCOUNT = 0; private static final int DIALOG_CREATE_DIR = 1; private static final int DIALOG_ABOUT_APP = 2; + private static final int ACTION_SELECT_FILE = 1; + //private static final int ACTION_CREATE_FIRST_ACCOUNT = 2; dvelasco: WIP @Override public void onCreate(Bundle savedInstanceState) { + Log.i(getClass().toString(), "onCreate() start"); super.onCreate(savedInstanceState); - // TODO: fix hack: workaround for bug in actionbar sherlock - // it always shows indeterminate progress bar - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - setProgressBarIndeterminateVisibility(false); - } + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + setSupportProgressBarIndeterminateVisibility(false); Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext())); if(savedInstanceState != null){ - mCurrentDir = (OCFile) savedInstanceState.getParcelable(KEY_CURRENT_DIR); + mCurrentDir = (OCFile) savedInstanceState.getParcelable(KEY_CURRENT_DIR); // this is never saved with this key :S } - if (findViewById(R.id.file_list_view) == null) - mLayoutView = getLayoutInflater().inflate(R.layout.files, null); // always inflate this at onCreate() ; just once! + mLayoutView = getLayoutInflater().inflate(R.layout.files, null); // always inflate this at onCreate() ; just once! - //TODO: Dialog useless -> get rid of this - if (!accountsAreSetup()) { + if (AccountUtils.accountsAreSetup(this)) { + setContentView(mLayoutView); + + } else { setContentView(R.layout.no_account_available); setProgressBarIndeterminateVisibility(false); getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE); findViewById(R.id.setup_account).setOnClickListener(this); - - } else if (findViewById(R.id.file_list_view) == null) { - setContentView(mLayoutView); } + Log.i(getClass().toString(), "onCreate() end"); } @Override @@ -151,6 +147,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements case R.id.startSync: { Bundle bundle = new Bundle(); bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); + bundle.putString("PROBANDO", "PARAMETRO PASADO AL SYNC"); ContentResolver.requestSync( AccountUtils.getCurrentOwnCloudAccount(this), "org.owncloud", bundle); @@ -199,8 +196,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements * Called, when the user selected something for uploading */ public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == RESULT_OK) { - if (requestCode == ACTION_SELECT_FILE) { + if (requestCode == ACTION_SELECT_FILE) { + if (resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); String filemanagerstring = selectedImageUri.getPath(); @@ -234,7 +231,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE); startService(i); } - } + + }/* dvelasco: WIP - not working as expected ... yet :) + else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) { + if (resultCode != RESULT_OK) { + finish(); // the user cancelled the AuthenticatorActivity + } + }*/ } @Override @@ -255,6 +258,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { + Log.i(getClass().toString(), "onRestoreInstanceState() start"); super.onRestoreInstanceState(savedInstanceState); mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY); mDirectories = new CustomArrayAdapter(this, R.layout.sherlock_spinner_dropdown_item); @@ -263,10 +267,12 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements for (String s : mDirs) mDirectories.insert(s, 0); mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE); + Log.i(getClass().toString(), "onRestoreInstanceState() end"); } @Override protected void onSaveInstanceState(Bundle outState) { + Log.i(getClass().toString(), "onSaveInstanceState() start"); super.onSaveInstanceState(outState); if(mDirectories != null && mDirectories.getCount() != 0){ mDirs = new String[mDirectories.getCount()-1]; @@ -276,20 +282,35 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements } outState.putStringArray(KEY_DIR_ARRAY, mDirs); outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir); + Log.i(getClass().toString(), "onSaveInstanceState() end"); } @Override protected void onResume() { + Log.i(getClass().toString(), "onResume() start"); super.onResume(); - if (accountsAreSetup()) { + if (!AccountUtils.accountsAreSetup(this)) { + /*Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT); + intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE }); + //startActivity(intent); + startActivityForResult(intent, ACTION_CREATE_FIRST_ACCOUNT);*/ + + } else { // at least an account exist: normal operation - setContentView(mLayoutView); // this should solve the crash by repeated inflating in big screens (DROIDCLOUD-27) + // set the layout only if it couldn't be set in onCreate + if (findViewById(R.id.file_list_view) == null) + setContentView(mLayoutView); // Listen for sync messages IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE); - syncBroadcastRevceiver = new SyncBroadcastReceiver(); - registerReceiver(syncBroadcastRevceiver, syncIntentFilter); + mSyncBroadcastReceiver = new SyncBroadcastReceiver(); + registerReceiver(mSyncBroadcastReceiver, syncIntentFilter); + + // Listen for upload messages + IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE); + mUploadFinishReceiver = new UploadFinishReceiver(); + registerReceiver(mUploadFinishReceiver, uploadIntentFilter); // Storage manager initialization mStorageManager = new FileDataStorageManager( @@ -355,16 +376,23 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements // List dir here mFileList.listDirectory(mCurrentDir); } + Log.i(getClass().toString(), "onResume() end"); } @Override protected void onPause() { + Log.i(getClass().toString(), "onPause() start"); super.onPause(); - if (syncBroadcastRevceiver != null) { - unregisterReceiver(syncBroadcastRevceiver); - syncBroadcastRevceiver = null; + if (mSyncBroadcastReceiver != null) { + unregisterReceiver(mSyncBroadcastReceiver); + mSyncBroadcastReceiver = null; + } + if (mUploadFinishReceiver != null) { + unregisterReceiver(mUploadFinishReceiver); + mUploadFinishReceiver = null; } getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir); + Log.i(getClass().toString(), "onPause() end"); } @Override @@ -520,18 +548,6 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements return !mDirectories.isEmpty(); } - /** - * Checks, whether or not there are any ownCloud accounts setup. - * - * @return true, if there is at least one account. - */ - private boolean accountsAreSetup() { - AccountManager accMan = AccountManager.get(this); - Account[] accounts = accMan - .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); - return accounts.length > 0; - } - private class DirectoryCreator implements Runnable { private String mTargetPath; private Account mAccount; @@ -598,17 +614,58 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements .getStringExtra(FileSyncService.ACCOUNT_NAME); Log.d("FileDisplay", "sync of account " + account_name + " is in_progress: " + inProgress); - setProgressBarIndeterminateVisibility(inProgress); + setSupportProgressBarIndeterminateVisibility(inProgress); + + long OCDirId = intent.getLongExtra(FileSyncService.SYNC_FOLDER, -1); + if (OCDirId > 0) { + OCFile syncDir = mStorageManager.getFileById(OCDirId); + if (syncDir != null && ( + (mCurrentDir == null && syncDir.getFileName().equals("/")) || + syncDir.equals(mCurrentDir)) + ) { + FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList); + if (fileListFragment != null) { + fileListFragment.listDirectory(); + } + } + } + if (!inProgress) { - FileListFragment fileListFramgent = (FileListFragment) getSupportFragmentManager() + FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager() .findFragmentById(R.id.fileList); - if (fileListFramgent != null) - fileListFramgent.listDirectory(); + if (fileListFragment != null) + fileListFragment.listDirectory(); } } } + + + private class UploadFinishReceiver extends BroadcastReceiver { + /** + * Once the file upload has finished -> update view + * @author David A. Velasco + * {@link BroadcastReceiver} to enable upload feedback in UI + */ + @Override + public void onReceive(Context context, Intent intent) { + long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1); + OCFile parentDir = mStorageManager.getFileById(parentDirId); + + if (parentDir != null && ( + (mCurrentDir == null && parentDir.getFileName().equals("/")) || + parentDir.equals(mCurrentDir)) + ) { + FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList); + if (fileListFragment != null) { + fileListFragment.listDirectory(); + } + } + } + + } + @Override public void onClick(View v) { if (v.getId() == R.id.setup_account) { diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java index ee695553..2badae1d 100644 --- a/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java +++ b/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java @@ -22,6 +22,7 @@ import java.util.List; import android.accounts.Account; import android.accounts.AccountManager; import android.app.ActionBar.LayoutParams; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -38,6 +39,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.webkit.MimeTypeMap; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; @@ -203,9 +205,13 @@ public class FileDetailFragment extends SherlockFragment implements if (mFile.getMimetype().startsWith("image/")) { BitmapFactory.Options options = new Options(); options.inScaled = true; - options.inMutable = false; - options.inPreferQualityOverSpeed = false; options.inPurgeable = true; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { + options.inPreferQualityOverSpeed = false; + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { + options.inMutable = false; + } Bitmap bmp = BitmapFactory.decodeFile(mFile.getStoragePath(), options); @@ -224,18 +230,55 @@ public class FileDetailFragment extends SherlockFragment implements } catch (OutOfMemoryError e) { preview.setVisibility(View.INVISIBLE); Log.e(TAG, "Out of memory occured for file with size " + mFile.getFileLength()); + + } catch (NoSuchFieldError e) { + preview.setVisibility(View.INVISIBLE); + Log.e(TAG, "Error from access to unexisting field despite protection " + mFile.getFileLength()); + + } catch (Throwable t) { + preview.setVisibility(View.INVISIBLE); + Log.e(TAG, "Unexpected error while creating image preview " + mFile.getFileLength(), t); } downloadButton.setText(R.string.filedetails_open); downloadButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setDataAndType(Uri.parse("file://"+mFile.getStoragePath()), mFile.getMimetype()); - List list = getActivity().getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY); - if (list.size() > 0) { + String storagePath = mFile.getStoragePath(); + try { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setDataAndType(Uri.parse("file://"+ storagePath), mFile.getMimetype()); + i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivity(i); - } else { - Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show(); + + } catch (Throwable t) { + Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype()); + boolean toastIt = true; + String mimeType = ""; + try { + Intent i = new Intent(Intent.ACTION_VIEW); + mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1)); + if (mimeType != mFile.getMimetype()) { + i.setDataAndType(Uri.parse("file://"+mFile.getStoragePath()), mimeType); + i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivity(i); + toastIt = false; + } + + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath); + + } catch (ActivityNotFoundException e) { + Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension"); + + } catch (Throwable th) { + Log.e(TAG, "Unexpected problem when opening: " + storagePath, th); + + } finally { + if (toastIt) { + Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show(); + } + } + } } }); @@ -306,7 +349,7 @@ public class FileDetailFragment extends SherlockFragment implements * the time that the file was created. There is a chance that this will * be fixed in future versions. Use this method to check if this version of * ownCloud has this fix. - * @return True, if ownCloud the ownCloud version is > 3.0.4 and 4.0.1 + * @return True, if ownCloud the ownCloud version is > 3.0.4 and 4.0.4 */ private boolean ocVersionSupportsTimeCreated(){ if(mIntent != null){ @@ -315,7 +358,7 @@ public class FileDetailFragment extends SherlockFragment implements AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE); OwnCloudVersion ocVersion = new OwnCloudVersion(accManager .getUserData(ocAccount, AccountAuthenticator.KEY_OC_VERSION)); - if(ocVersion.compareTo(new OwnCloudVersion(0x030004)) >= 0 || ocVersion.compareTo(new OwnCloudVersion(0x040001)) >= 0){ + if(ocVersion.compareTo(new OwnCloudVersion(0x030004)) >= 0 || ocVersion.compareTo(new OwnCloudVersion(0x040004)) >= 0){ return true; } } diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java index 3aedfad3..895b3a28 100644 --- a/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java +++ b/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java @@ -50,36 +50,40 @@ import eu.alefzero.owncloud.ui.adapter.FileListListAdapter; */ public class FileListFragment extends FragmentListView { private static final String TAG = "FileListFragment"; - //private Account mAccount; // dvelasco : the fragment is not recreated when other account is selected; keep as an attribute is dangerous + private Vector mFiles; - //private DataStorageManager mStorageManager; // dvelasco : just the same; it depends upon the current account ; it's updated in FileDisplayActivity!! private OCFile mFile; - private boolean mIsLargeDevice = false; + private boolean mIsLargeDevice; @Override public void onCreate(Bundle savedInstanceState) { + Log.i(getClass().toString(), "onCreate() start"); super.onCreate(savedInstanceState); Intent intent = getActivity().getIntent(); OCFile directory = intent.getParcelableExtra(FileDetailFragment.EXTRA_FILE); mFile = directory; + mIsLargeDevice = false; + Log.i(getClass().toString(), "onCreate() stop"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Log.i(getClass().toString(), "onCreateView() start"); super.onCreateView(inflater, container, savedInstanceState); getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator)); getListView().setDividerHeight(1); - //listDirectory(mFile); - + Log.i(getClass().toString(), "onCreateView() end"); return getListView(); } @Override public void onStart() { + Log.i(getClass().toString(), "onStart() start"); + super.onStart(); // Create a placeholder upon launch View fragmentContainer = getActivity().findViewById(R.id.file_details_container); if (fragmentContainer != null) { @@ -88,7 +92,7 @@ public class FileListFragment extends FragmentListView { transaction.replace(R.id.file_details_container, new FileDetailFragment(true)); transaction.commit(); } - super.onStart(); + Log.i(getClass().toString(), "onStart() end"); } @Override @@ -206,16 +210,10 @@ public class FileListFragment extends FragmentListView { mFile = directory; mFiles = storageManager.getDirectoryContent(directory); - if (mFiles == null || mFiles.size() == 0) { + /*if (mFiles == null || mFiles.size() == 0) { Toast.makeText(getActivity(), "There are no files here", Toast.LENGTH_LONG).show(); - } + }*/ setListAdapter(new FileListListAdapter(directory, storageManager, getActivity())); } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putParcelable("ACCOUNT", AccountUtils.getCurrentOwnCloudAccount(getActivity())); - } - } diff --git a/src/eu/alefzero/webdav/WebdavEntry.java b/src/eu/alefzero/webdav/WebdavEntry.java index 032d996a..f4fbda45 100644 --- a/src/eu/alefzero/webdav/WebdavEntry.java +++ b/src/eu/alefzero/webdav/WebdavEntry.java @@ -52,6 +52,10 @@ public class WebdavEntry { prop = propSet.get(DavPropertyName.GETCONTENTTYPE); if (prop != null) { mContentType = (String) prop.getValue(); + // dvelasco: some builds of ownCloud server 4.0.x added a trailing ';' to the MIME type ; if looks fixed, but let's be cautious + if (mContentType.indexOf(";") >= 0) { + mContentType = mContentType.substring(0, mContentType.indexOf(";")); + } } else { mContentType = "DIR"; /*