From: David A. Velasco Date: Tue, 4 Feb 2014 13:19:23 +0000 (+0100) Subject: Connected selection of app to send share link with creation of share resource, and... X-Git-Tag: oc-android-1.5.5~58^2~14 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/e2a4ad78de381058300972aa61072de086f3feeb Connected selection of app to send share link with creation of share resource, and link send to chosen app --- diff --git a/owncloud-android-library b/owncloud-android-library index 09b1c3c1..764fb105 160000 --- a/owncloud-android-library +++ b/owncloud-android-library @@ -1 +1 @@ -Subproject commit 09b1c3c15aa2644635796c93ee918f8b0a20ff7c +Subproject commit 764fb1058fba09f5c06ba48cd700ed417d0f73a4 diff --git a/src/com/owncloud/android/files/FileHandler.java b/src/com/owncloud/android/files/FileHandler.java deleted file mode 100644 index 77ff78ad..00000000 --- a/src/com/owncloud/android/files/FileHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ownCloud Android client application - * Copyright (C) 2012-2013 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.owncloud.android.files; - -import com.owncloud.android.datamodel.OCFile; - -public interface FileHandler { - - /** - * TODO - */ - public void openFile(OCFile file); - - - public void shareFileWithLink(OCFile file); -} diff --git a/src/com/owncloud/android/files/FileOperationsHelper.java b/src/com/owncloud/android/files/FileOperationsHelper.java new file mode 100644 index 00000000..41e7110b --- /dev/null +++ b/src/com/owncloud/android/files/FileOperationsHelper.java @@ -0,0 +1,142 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.owncloud.android.files; + +import org.apache.http.protocol.HTTP; + +import android.accounts.AccountManager; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.app.DialogFragment; +import android.webkit.MimeTypeMap; +import android.widget.Toast; + +import com.owncloud.android.R; +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.lib.accounts.OwnCloudAccount; +import com.owncloud.android.lib.network.webdav.WebdavUtils; +import com.owncloud.android.lib.operations.common.ShareType; +import com.owncloud.android.operations.CreateShareOperation; +import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.ui.dialog.ActivityChooserDialog; +import com.owncloud.android.utils.Log_OC; + +/** + * + * @author masensio + * @author David A. Velasco + */ +public class FileOperationsHelper { + + private static final String TAG = FileOperationsHelper.class.getName(); + + private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; + + + public void openFile(OCFile file, FileActivity callerActivity) { + if (file != null) { + String storagePath = file.getStoragePath(); + String encodedStoragePath = WebdavUtils.encodePath(storagePath); + + Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW); + intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype()); + intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + + Intent intentForGuessedMimeType = null; + if (storagePath.lastIndexOf('.') >= 0) { + String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1)); + if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) { + intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW); + intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType); + intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } + } + + Intent chooserIntent = null; + if (intentForGuessedMimeType != null) { + chooserIntent = Intent.createChooser(intentForGuessedMimeType, callerActivity.getString(R.string.actionbar_open_with)); + } else { + chooserIntent = Intent.createChooser(intentForSavedMimeType, callerActivity.getString(R.string.actionbar_open_with)); + } + + callerActivity.startActivity(chooserIntent); + + } else { + Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); + } + } + + + public void shareFileWithLink(OCFile file, FileActivity callerActivity) { + + if (isSharedSupported(callerActivity)) { + if (file != null) { + String link = "https://fake.url"; + Intent intent = createShareWithLinkIntent(link); + String[] packagesToExclude = new String[] { callerActivity.getPackageName() }; + DialogFragment chooserDialog = ActivityChooserDialog.newInstance(intent, packagesToExclude, file); + chooserDialog.show(callerActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); + + } else { + Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); + } + + } else { + // Show a Message + Toast t = Toast.makeText(callerActivity, callerActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG); + t.show(); + } + } + + + public void shareFileWithLinkToApp(OCFile file, Intent sendIntent, FileActivity callerActivity) { + + if (file != null) { + CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1, sendIntent); + createShare.execute(callerActivity.getStorageManager(), + callerActivity, + callerActivity.getRemoteOperationListener(), + callerActivity.getHandler(), + callerActivity); + + } else { + Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); + } + } + + + private Intent createShareWithLinkIntent(String link) { + Intent intentToShareLink = new Intent(Intent.ACTION_SEND); + intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); + intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); + return intentToShareLink; + } + + + /** + * @return 'True' if the server supports the Share API + */ + public boolean isSharedSupported(FileActivity callerActivity) { + if (callerActivity.getAccount() != null) { + AccountManager accountManager = AccountManager.get(callerActivity); + return Boolean.parseBoolean(accountManager.getUserData(callerActivity.getAccount(), OwnCloudAccount.Constants.KEY_SUPPORTS_SHARE_API)); + } + return false; + } + +} diff --git a/src/com/owncloud/android/operations/CreateShareOperation.java b/src/com/owncloud/android/operations/CreateShareOperation.java index 7659d16d..71147c64 100644 --- a/src/com/owncloud/android/operations/CreateShareOperation.java +++ b/src/com/owncloud/android/operations/CreateShareOperation.java @@ -24,6 +24,8 @@ package com.owncloud.android.operations; * */ +import android.content.Intent; + import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.network.OwnCloudClient; @@ -47,6 +49,7 @@ public class CreateShareOperation extends SyncOperation { private boolean mPublicUpload; private String mPassword; private int mPermissions; + private Intent mSendIntent; /** * Constructor @@ -67,7 +70,7 @@ public class CreateShareOperation extends SyncOperation { * For instance, for “Re-Share”, “delete”, “read”, “update”, add 16+8+2+1 = 27. */ public CreateShareOperation(String path, ShareType shareType, String shareWith, boolean publicUpload, - String password, int permissions) { + String password, int permissions, Intent sendIntent) { mPath = path; mShareType = shareType; @@ -75,6 +78,7 @@ public class CreateShareOperation extends SyncOperation { mPublicUpload = publicUpload; mPassword = password; mPermissions = permissions; + mSendIntent = sendIntent; } @Override @@ -103,6 +107,7 @@ public class CreateShareOperation extends SyncOperation { // Update OCFile with data from share: ShareByLink and publicLink OCFile file = getStorageManager().getFileByPath(mPath); if (file!=null) { + mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink()); file.setPublicLink(share.getShareLink()); getStorageManager().saveFile(file); Log_OC.d(TAG, "Public Link = " + file.getPublicLink()); @@ -114,5 +119,10 @@ public class CreateShareOperation extends SyncOperation { return result; } + + + public Intent getSendIntent() { + return mSendIntent; + } } diff --git a/src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java b/src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java index 5b22c341..fbbc5dff 100644 --- a/src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java +++ b/src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java @@ -19,7 +19,6 @@ package com.owncloud.android.ui.activity; import com.actionbarsherlock.app.ActionBar; -import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileUploader; import com.owncloud.android.ui.dialog.ConflictsResolveDialog; @@ -77,6 +76,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict @Override protected void onAccountSet(boolean stateWasRecovered) { + super.onAccountSet(stateWasRecovered); if (getAccount() != null) { OCFile file = getFile(); if (getFile() == null) { @@ -84,8 +84,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict finish(); } else { /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account - FileDataStorageManager storageManager = new FileDataStorageManager(getAccount(), getContentResolver()); - file = storageManager.getFileByPath(file.getRemotePath()); // file = null if not in the current Account + file = getStorageManager().getFileByPath(file.getRemotePath()); // file = null if not in the current Account if (file != null) { setFile(file); ConflictsResolveDialog d = ConflictsResolveDialog.newInstance(file.getRemotePath(), this); @@ -98,7 +97,6 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict } } else { - Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); finish(); } diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java index 07c5b536..f43ee8d7 100644 --- a/src/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/com/owncloud/android/ui/activity/FileActivity.java @@ -18,30 +18,24 @@ package com.owncloud.android.ui.activity; -import org.apache.http.protocol.HTTP; - import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.accounts.OperationCanceledException; -import android.support.v4.app.DialogFragment; -import android.content.Intent; -import android.net.Uri; import android.os.Bundle; -import android.webkit.MimeTypeMap; -import android.widget.Toast; +import android.os.Handler; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.owncloud.android.MainApp; -import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; +import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.files.FileOperationsHelper; +import com.owncloud.android.lib.operations.common.OnRemoteOperationListener; +import com.owncloud.android.lib.operations.common.RemoteOperation; +import com.owncloud.android.lib.operations.common.RemoteOperationResult; -import com.owncloud.android.lib.accounts.OwnCloudAccount; -import com.owncloud.android.lib.network.webdav.WebdavUtils; - -import com.owncloud.android.ui.dialog.ActivityChooserDialog; import com.owncloud.android.utils.Log_OC; @@ -50,7 +44,7 @@ import com.owncloud.android.utils.Log_OC; * * @author David A. Velasco */ -public abstract class FileActivity extends SherlockFragmentActivity { +public class FileActivity extends SherlockFragmentActivity implements OnRemoteOperationListener { public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE"; public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT"; @@ -59,8 +53,6 @@ public abstract class FileActivity extends SherlockFragmentActivity { public static final String TAG = FileActivity.class.getSimpleName(); - private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; - /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. */ private Account mAccount; @@ -80,6 +72,13 @@ public abstract class FileActivity extends SherlockFragmentActivity { /** Flag to signal if the activity is launched by a notification */ private boolean mFromNotification; + /** Messages handler associated to the main thread and the life cycle of the activity */ + private Handler mHandler; + + /** Access point to the cached database for the current ownCloud {@link Account} */ + private FileDataStorageManager mStorageManager = null; + + private FileOperationsHelper mFileOperationsHelper; /** @@ -92,6 +91,8 @@ public abstract class FileActivity extends SherlockFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mHandler = new Handler(); + mFileOperationsHelper = new FileOperationsHelper(); Account account; if(savedInstanceState != null) { account = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT); @@ -257,17 +258,6 @@ public abstract class FileActivity extends SherlockFragmentActivity { /** - * @return 'True' if the server supports the Share API - */ - public boolean isSharedSupported() { - if (getAccount() != null) { - AccountManager accountManager = AccountManager.get(this); - return Boolean.parseBoolean(accountManager.getUserData(getAccount(), OwnCloudAccount.Constants.KEY_SUPPORTS_SHARE_API)); - } - return false; - } - - /** * Helper class handling a callback from the {@link AccountManager} after the creation of * a new ownCloud {@link Account} finished, successfully or not. * @@ -314,93 +304,44 @@ public abstract class FileActivity extends SherlockFragmentActivity { * * Child classes must grant that state depending on the {@link Account} is updated. */ - protected abstract void onAccountSet(boolean stateWasRecovered); - - - - public void openFile(OCFile file) { - if (file != null) { - String storagePath = file.getStoragePath(); - String encodedStoragePath = WebdavUtils.encodePath(storagePath); - - Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW); - intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype()); - intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - - Intent intentForGuessedMimeType = null; - if (storagePath.lastIndexOf('.') >= 0) { - String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1)); - if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) { - intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW); - intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType); - intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - } - } - - Intent chooserIntent = null; - if (intentForGuessedMimeType != null) { - chooserIntent = Intent.createChooser(intentForGuessedMimeType, getString(R.string.actionbar_open_with)); - } else { - chooserIntent = Intent.createChooser(intentForSavedMimeType, getString(R.string.actionbar_open_with)); - } - - startActivity(chooserIntent); + protected void onAccountSet(boolean stateWasRecovered) { + if (getAccount() != null) { + mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); } else { - Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); + Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); } } - /* - public void shareFileWithLink(OCFile file) { - if (file != null) { - - Intent intentToShareLink = new Intent(Intent.ACTION_SEND); - intentToShareLink.putExtra(Intent.EXTRA_TEXT, "https://fake.url.lolo"); - intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); - - Intent chooserIntent = Intent.createChooser(intentToShareLink, getString(R.string.action_share_file)); - startActivity(chooserIntent); - - } else { - Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); - } + + public FileDataStorageManager getStorageManager() { + return mStorageManager; } - */ - - public void shareFileWithLink(OCFile file) { - if (isSharedSupported()) { - if (file != null) { - - // Create the Share - TODO integrate before or after the chooser menu - //CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1); - //createShare.execute(getStorageManager(), this, this, mHandler, this); - - // TODO Get the link --> when the operation is finished - String link = "https://fake.url.lolo"; - - Intent intent = createShareWithLinkIntent(link); - String[] packagesToExclude = new String[] { getPackageName() }; - DialogFragment chooserDialog = ActivityChooserDialog.newInstance(intent, packagesToExclude); - chooserDialog.show(getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); - - } else { - Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); - } - - } else { - // Show a Message - Toast t = Toast.makeText(this, getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG); - t.show(); - } + + + public OnRemoteOperationListener getRemoteOperationListener() { + return this; } - - private Intent createShareWithLinkIntent(String link) { - Intent intentToShareLink = new Intent(Intent.ACTION_SEND); - intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); - intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); - return intentToShareLink; + + + public Handler getHandler() { + return mHandler; } + public FileOperationsHelper getFileOperationsHelper() { + return mFileOperationsHelper; + } + /** + * + * @param operation Removal operation performed. + * @param result Result of the removal. + */ + @Override + public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { + // does nothing ; to override in child classes + Log_OC.d(TAG, "Received result of operation in FileActivity"); + } + + } diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index 237113d8..692b5b03 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -38,7 +38,6 @@ import android.content.res.Resources.NotFoundException; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.MediaStore; @@ -61,7 +60,6 @@ import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.Window; import com.owncloud.android.MainApp; import com.owncloud.android.R; -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.FileObserverService; @@ -70,7 +68,6 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.operations.CreateFolderOperation; -import com.owncloud.android.lib.operations.common.OnRemoteOperationListener; import com.owncloud.android.lib.operations.common.RemoteOperation; import com.owncloud.android.lib.operations.common.RemoteOperationResult; import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode; @@ -104,13 +101,10 @@ import com.owncloud.android.utils.Log_OC; */ public class FileDisplayActivity extends FileActivity implements -OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, OnRemoteOperationListener, EditNameDialogListener { +OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, EditNameDialogListener { private ArrayAdapter mDirectories; - /** Access point to the cached database for the current ownCloud {@link Account} */ - private FileDataStorageManager mStorageManager = null; - private SyncBroadcastReceiver mSyncBroadcastReceiver; private UploadFinishReceiver mUploadFinishReceiver; private DownloadFinishReceiver mDownloadFinishReceiver; @@ -146,7 +140,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa private static final String TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT"; private OCFile mWaitingToPreview; - private Handler mHandler; private boolean mSyncInProgress = false; private boolean mRefreshSharesInProgress = false; @@ -158,8 +151,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account is valid - mHandler = new Handler(); - /// bindings to transference services mUploadConnection = new ListServiceConnection(); mDownloadConnection = new ListServiceConnection(); @@ -230,9 +221,8 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa */ @Override protected void onAccountSet(boolean stateWasRecovered) { + super.onAccountSet(stateWasRecovered); if (getAccount() != null) { - mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); - /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account OCFile file = getFile(); // get parent from path @@ -242,15 +232,15 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa // upload in progress - right now, files are not inserted in the local cache until the upload is successful // get parent from path parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName())); - if (mStorageManager.getFileByPath(parentPath) == null) + if (getStorageManager().getFileByPath(parentPath) == null) file = null; // not able to know the directory where the file is uploading } else { - file = mStorageManager.getFileByPath(file.getRemotePath()); // currentDir = null if not in the current Account + file = getStorageManager().getFileByPath(file.getRemotePath()); // currentDir = null if not in the current Account } } if (file == null) { // fall back to root folder - file = mStorageManager.getFileByPath(OCFile.ROOT_PATH); // never returns null + file = getStorageManager().getFileByPath(OCFile.ROOT_PATH); // never returns null } setFile(file); setNavigationListWithFolder(file); @@ -266,10 +256,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa updateFragmentsVisibility(!file.isFolder()); updateNavigationElementsInActionBar(file.isFolder() ? null : file); } - - - } else { - Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); } } @@ -282,10 +268,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (fileIt.isFolder()) { mDirectories.add(fileIt.getFileName()); } - //fileIt = mStorageManager.getFileById(fileIt.getParentId()); // get parent from path parentPath = fileIt.getRemotePath().substring(0, fileIt.getRemotePath().lastIndexOf(fileIt.getFileName())); - fileIt = mStorageManager.getFileByPath(parentPath); + fileIt = getStorageManager().getFileByPath(parentPath); } mDirectories.add(OCFile.PATH_SEPARATOR); } @@ -447,12 +432,12 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa boolean detailsFragmentChanged = false; if (waitedPreview) { if (success) { - mWaitingToPreview = mStorageManager.getFileById(mWaitingToPreview.getFileId()); // update the file from database, for the local storage path + mWaitingToPreview = getStorageManager().getFileById(mWaitingToPreview.getFileId()); // update the file from database, for the local storage path if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) { startMediaPreview(mWaitingToPreview, 0, true); detailsFragmentChanged = true; } else { - openFile(mWaitingToPreview); + getFileOperationsHelper().openFile(mWaitingToPreview, this); } } mWaitingToPreview = null; @@ -464,7 +449,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa } } - @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getSherlock().getMenuInflater(); @@ -543,7 +527,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa targetPath = mDirectories.getItem(i) + OCFile.PATH_SEPARATOR + targetPath; } targetPath = OCFile.PATH_SEPARATOR + targetPath; - OCFile targetFolder = mStorageManager.getFileByPath(targetPath); + OCFile targetFolder = getStorageManager().getFileByPath(targetPath); if (targetFolder != null) { browseTo(targetFolder); } @@ -933,12 +917,12 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncService.SYNC_RESULT); if (getAccount() != null && accountName.equals(getAccount().name) - && mStorageManager != null) { + && getStorageManager() != null) { String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH); - OCFile currentFile = (getFile() == null) ? null : mStorageManager.getFileByPath(getFile().getRemotePath()); - OCFile currentDir = (getCurrentDir() == null) ? null : mStorageManager.getFileByPath(getCurrentDir().getRemotePath()); + OCFile currentFile = (getFile() == null) ? null : getStorageManager().getFileByPath(getFile().getRemotePath()); + OCFile currentDir = (getCurrentDir() == null) ? null : getStorageManager().getFileByPath(getCurrentDir().getRemotePath()); if (currentDir == null) { // current folder was removed from the server @@ -966,7 +950,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (!mRefreshSharesInProgress) { /// get the shared files - if (isSharedSupported()) { + if (getFileOperationsHelper().isSharedSupported(FileDisplayActivity.this)) { startGetShares(); } setSupportProgressBarIndeterminateVisibility(inProgress); @@ -1064,7 +1048,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa Account account = intent.getParcelableExtra(OperationsService.EXTRA_ACCOUNT); RemoteOperationResult getSharesResult = (RemoteOperationResult)intent.getSerializableExtra(OperationsService.EXTRA_RESULT); if (getAccount() != null && account.name.equals(getAccount().name) - && mStorageManager != null + && getStorageManager() != null ) { refeshListOfFilesFragment(); } @@ -1081,23 +1065,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa } - - /** - * {@inheritDoc} - */ - @Override - public FileDataStorageManager getStorageManager() { - return mStorageManager; - } - - public void browseToRoot() { OCFileListFragment listOfFiles = getListOfFilesFragment(); if (listOfFiles != null) { // should never be null, indeed while (mDirectories.getCount() > 1) { popDirname(); } - OCFile root = mStorageManager.getFileByPath(OCFile.ROOT_PATH); + OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH); listOfFiles.listDirectory(root); setFile(listOfFiles.getCurrentFile()); startSyncFolderOperation(root); @@ -1346,21 +1320,25 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa onCreateFolderOperationFinish((CreateFolderOperation)operation, result); } else if (operation instanceof CreateShareOperation) { - onCreateShareOperation((CreateShareOperation) operation, result); + onCreateShareOperationFinish((CreateShareOperation) operation, result); } } - private void onCreateShareOperation(CreateShareOperation operation, RemoteOperationResult result) { + private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) { if (result.getCode() == ResultCode.FILE_NOT_FOUND) { // Show a Message Toast t = Toast.makeText(this, getString(R.string.share_link_file_no_exist), Toast.LENGTH_LONG); t.show(); + + } else if (result.isSuccess()) { + refeshListOfFilesFragment(); + + Intent sendIntent = operation.getSendIntent(); + startActivity(sendIntent); } - refeshListOfFilesFragment(); - } /** @@ -1381,7 +1359,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (second != null && removedFile.equals(second.getFile())) { cleanSecondFragment(); } - if (mStorageManager.getFileById(removedFile.getParentId()).equals(getCurrentDir())) { + if (getStorageManager().getFileById(removedFile.getParentId()).equals(getCurrentDir())) { refeshListOfFilesFragment(); } @@ -1440,7 +1418,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa ((FileDetailFragment) details).updateFileDetails(renamedFile, getAccount()); } } - if (mStorageManager.getFileById(renamedFile.getParentId()).equals(getCurrentDir())) { + if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())) { refeshListOfFilesFragment(); } @@ -1516,11 +1494,11 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa // Create directory path += newDirectoryName + OCFile.PATH_SEPARATOR; - RemoteOperation operation = new CreateFolderOperation(path, false, mStorageManager); + RemoteOperation operation = new CreateFolderOperation(path, false, getStorageManager()); operation.execute( getAccount(), FileDisplayActivity.this, FileDisplayActivity.this, - mHandler, + getHandler(), FileDisplayActivity.this); showLoadingDialog(); @@ -1545,9 +1523,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (file != null) { if (file.isFolder()) { return file; - } else if (mStorageManager != null) { + } else if (getStorageManager() != null) { String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName())); - return mStorageManager.getFileByPath(parentPath); + return getStorageManager().getFileByPath(parentPath); } } return null; diff --git a/src/com/owncloud/android/ui/activity/UploadFilesActivity.java b/src/com/owncloud/android/ui/activity/UploadFilesActivity.java index 7eff9b45..8b4a41d2 100644 --- a/src/com/owncloud/android/ui/activity/UploadFilesActivity.java +++ b/src/com/owncloud/android/ui/activity/UploadFilesActivity.java @@ -380,6 +380,7 @@ public class UploadFilesActivity extends FileActivity implements @Override protected void onAccountSet(boolean stateWasRecovered) { + super.onAccountSet(stateWasRecovered); if (getAccount() != null) { if (!mAccountOnCreation.equals(getAccount())) { setResult(RESULT_CANCELED); @@ -387,7 +388,6 @@ public class UploadFilesActivity extends FileActivity implements } } else { - Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); setResult(RESULT_CANCELED); finish(); } diff --git a/src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java b/src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java index 133f46b9..dc15f69a 100644 --- a/src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java +++ b/src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java @@ -24,9 +24,11 @@ import java.util.List; import android.app.AlertDialog; import android.app.Dialog; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; @@ -35,11 +37,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; -import android.widget.ListAdapter; import android.widget.TextView; import com.actionbarsherlock.app.SherlockDialogFragment; import com.owncloud.android.R; +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.files.FileOperationsHelper; +import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.utils.Log_OC; /** @@ -53,14 +57,18 @@ public class ActivityChooserDialog extends SherlockDialogFragment { private final static String TAG = ActivityChooserDialog.class.getSimpleName(); private final static String ARG_INTENT = ActivityChooserDialog.class.getSimpleName() + ".ARG_INTENT"; private final static String ARG_PACKAGES_TO_EXCLUDE = ActivityChooserDialog.class.getSimpleName() + ".ARG_PACKAGES_TO_EXCLUDE"; + private final static String ARG_FILE_TO_SHARE = ActivityChooserDialog.class.getSimpleName() + ".FILE_TO_SHARE"; - private ListAdapter mAdapter; + private ActivityAdapter mAdapter; + private OCFile mFile; + private Intent mIntent; - public static ActivityChooserDialog newInstance(Intent intent, String[] packagesToExclude/*OnConflictDecisionMadeListener listener*/) { + public static ActivityChooserDialog newInstance(Intent intent, String[] packagesToExclude, OCFile fileToShare) { ActivityChooserDialog f = new ActivityChooserDialog(); Bundle args = new Bundle(); args.putParcelable(ARG_INTENT, intent); args.putStringArray(ARG_PACKAGES_TO_EXCLUDE, packagesToExclude); + args.putParcelable(ARG_FILE_TO_SHARE, fileToShare); f.setArguments(args); return f; } @@ -72,12 +80,13 @@ public class ActivityChooserDialog extends SherlockDialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - Intent intent = getArguments().getParcelable(ARG_INTENT); + mIntent = getArguments().getParcelable(ARG_INTENT); String[] packagesToExclude = getArguments().getStringArray(ARG_PACKAGES_TO_EXCLUDE); List packagesToExcludeList = Arrays.asList(packagesToExclude != null ? packagesToExclude : new String[0]); + mFile = getArguments().getParcelable(ARG_FILE_TO_SHARE); PackageManager pm= getSherlockActivity().getPackageManager(); - List activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + List activities = pm.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY); Iterator it = activities.iterator(); ResolveInfo resolveInfo; while (it.hasNext()) { @@ -94,8 +103,15 @@ public class ActivityChooserDialog extends SherlockDialogFragment { .setAdapter(mAdapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - // The 'which' argument contains the index position - // of the selected item + // Add the information of the chosen activity to the intent to send + ResolveInfo chosen = mAdapter.getItem(which); + ActivityInfo actInfo = chosen.activityInfo; + ComponentName name=new ComponentName(actInfo.applicationInfo.packageName, actInfo.name); + mIntent.setComponent(name); + + // Create a new share resource + FileOperationsHelper foh = new FileOperationsHelper(); + foh.shareFileWithLinkToApp(mFile, mIntent, (FileActivity)getSherlockActivity()); } }) .create(); @@ -107,7 +123,6 @@ public class ActivityChooserDialog extends SherlockDialogFragment { private PackageManager mPackageManager; ActivityAdapter(Context context, PackageManager pm, List apps) { - //super(context, android.R.layout.activity_list_item, apps); super(context, R.layout.activity_row, apps); this.mPackageManager = pm; } @@ -123,15 +138,12 @@ public class ActivityChooserDialog extends SherlockDialogFragment { private View newView(ViewGroup parent) { return(((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.activity_row, parent, false)); - //return(((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.activity_list_item, parent, false)); } private void bindView(int position, View row) { TextView label = (TextView) row.findViewById(R.id.title); - //TextView label = (TextView) row.findViewById(android.R.id.text1); label.setText(getItem(position).loadLabel(mPackageManager)); ImageView icon = (ImageView) row.findViewById(R.id.icon); - //ImageView icon = (ImageView) row.findViewById(android.R.id.icon); icon.setImageDrawable(getItem(position).loadIcon(mPackageManager)); } } diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 0eacfe44..216cceec 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -336,11 +336,13 @@ public class FileDetailFragment extends FileFragment implements public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_share_file: { - mContainerActivity.shareFileWithLink(getFile()); + FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity(); + activity.getFileOperationsHelper().shareFileWithLink(getFile(), activity); return true; } case R.id.action_open_file_with: { - mContainerActivity.openFile(getFile()); + FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity(); + activity.getFileOperationsHelper().openFile(getFile(), activity); return true; } case R.id.action_remove_file: { diff --git a/src/com/owncloud/android/ui/fragment/FileFragment.java b/src/com/owncloud/android/ui/fragment/FileFragment.java index 020eded1..2f1a49b1 100644 --- a/src/com/owncloud/android/ui/fragment/FileFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileFragment.java @@ -21,7 +21,6 @@ import android.support.v4.app.Fragment; import com.actionbarsherlock.app.SherlockFragment; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.FileHandler; import com.owncloud.android.ui.activity.TransferServiceGetter; @@ -73,7 +72,7 @@ public class FileFragment extends SherlockFragment { * * @author David A. Velasco */ - public interface ContainerActivity extends TransferServiceGetter, FileHandler { + public interface ContainerActivity extends TransferServiceGetter { /** * Callback method invoked when the detail fragment wants to notice its container @@ -96,9 +95,6 @@ public class FileFragment extends SherlockFragment { */ public void showDetails(OCFile file); - public void shareFileWithLink(OCFile file); - - } } diff --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 8be94778..96aa2dc2 100644 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -25,7 +25,6 @@ import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.FileHandler; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.lib.operations.common.OnRemoteOperationListener; @@ -183,8 +182,8 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName // media preview mContainerActivity.startMediaPreview(file, 0, true); } else { - // open with - mContainerActivity.openFile(file); + FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity(); + activity.getFileOperationsHelper().openFile(file, activity); } } else { @@ -285,7 +284,8 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName mTargetFile = (OCFile) mAdapter.getItem(info.position); switch (item.getItemId()) { case R.id.action_share_file: { - mContainerActivity.shareFileWithLink(mTargetFile); + FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity(); + activity.getFileOperationsHelper().shareFileWithLink(mTargetFile, activity); return true; } case R.id.action_rename_file: { @@ -414,7 +414,7 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName * * @author David A. Velasco */ - public interface ContainerActivity extends TransferServiceGetter, OnRemoteOperationListener, FileHandler { + public interface ContainerActivity extends TransferServiceGetter, OnRemoteOperationListener { /** * Callback method invoked when a the user browsed into a different folder through the list of files @@ -423,8 +423,6 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName */ public void onBrowsedDownTo(OCFile folder); - public void shareFileWithLink(OCFile currentFile); - public void startDownloadForPreview(OCFile file); public void startMediaPreview(OCFile file, int i, boolean b); diff --git a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java index 3caa80a0..374a53b7 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -70,8 +70,6 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT"; - private FileDataStorageManager mStorageManager; - private ViewPager mViewPager; private PreviewImagePagerAdapter mPreviewImagePagerAdapter; @@ -115,13 +113,12 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C private void initViewPager() { // get parent from path String parentPath = getFile().getRemotePath().substring(0, getFile().getRemotePath().lastIndexOf(getFile().getFileName())); - OCFile parentFolder = mStorageManager.getFileByPath(parentPath); - //OCFile parentFolder = mStorageManager.getFileById(getFile().getParentId()); + OCFile parentFolder = getStorageManager().getFileByPath(parentPath); if (parentFolder == null) { // should not be necessary - parentFolder = mStorageManager.getFileByPath(OCFile.ROOT_PATH); + parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH); } - mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), parentFolder, getAccount(), mStorageManager); + mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), parentFolder, getAccount(), getStorageManager()); mViewPager = (ViewPager) findViewById(R.id.fragmentPager); int position = mPreviewImagePagerAdapter.getFilePosition(getFile()); position = (position >= 0) ? position : 0; @@ -385,7 +382,7 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C if (getAccount().name.equals(accountName) && downloadedRemotePath != null) { - OCFile file = mStorageManager.getFileByPath(downloadedRemotePath); + OCFile file = getStorageManager().getFileByPath(downloadedRemotePath); int position = mPreviewImagePagerAdapter.getFilePosition(file); boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false); //boolean isOffscreen = Math.abs((mViewPager.getCurrentItem() - position)) <= mViewPager.getOffscreenPageLimit(); @@ -433,6 +430,7 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C @Override protected void onAccountSet(boolean stateWasRecovered) { + super.onAccountSet(stateWasRecovered); if (getAccount() != null) { OCFile file = getFile(); /// Validate handled file (first image to preview) @@ -442,15 +440,14 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C if (!file.isImage()) { throw new IllegalArgumentException("Non-image file passed as argument"); } - mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); // Update file according to DB file, if it is possible if (file.getFileId() > FileDataStorageManager.ROOT_PARENT_ID) - file = mStorageManager.getFileById(file.getFileId()); + file = getStorageManager().getFileById(file.getFileId()); if (file != null) { /// Refresh the activity according to the Account and OCFile set - setFile(file); // reset after getting it fresh from mStorageManager + setFile(file); // reset after getting it fresh from storageManager getSupportActionBar().setTitle(getFile().getFileName()); //if (!stateWasRecovered) { initViewPager(); @@ -460,9 +457,6 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C // handled file not in the current Account finish(); } - - } else { - Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); } } diff --git a/src/com/owncloud/android/ui/preview/PreviewVideoActivity.java b/src/com/owncloud/android/ui/preview/PreviewVideoActivity.java index 9e6a2803..5e5999b4 100644 --- a/src/com/owncloud/android/ui/preview/PreviewVideoActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewVideoActivity.java @@ -18,7 +18,6 @@ package com.owncloud.android.ui.preview; import com.owncloud.android.R; -import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.media.MediaService; import com.owncloud.android.ui.activity.FileActivity; @@ -60,8 +59,6 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi private static final String TAG = PreviewVideoActivity.class.getSimpleName(); - private FileDataStorageManager mStorageManager; - private int mSavedPlaybackPosition; // in the unit time handled by MediaPlayer.getCurrentPosition() private boolean mAutoplay; // when 'true', the playback starts immediately with the activity private VideoView mVideoPlayer; // view to play the file; both performs and show the playback @@ -194,6 +191,7 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi @Override protected void onAccountSet(boolean stateWasRecovered) { + super.onAccountSet(stateWasRecovered); if (getAccount() != null) { OCFile file = getFile(); /// Validate handled file (first image to preview) @@ -203,8 +201,7 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi if (!file.isVideo()) { throw new IllegalArgumentException("Non-video file passed as argument"); } - mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); - file = mStorageManager.getFileById(file.getFileId()); + file = getStorageManager().getFileById(file.getFileId()); if (file != null) { if (file.isDown()) { mVideoPlayer.setVideoPath(file.getStoragePath()); @@ -230,7 +227,6 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi finish(); } } else { - Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!"); finish(); } }