From d34b1e8da7f811eb809af65684344204650fb946 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Fri, 16 Oct 2020 11:51:37 +0200 Subject: [PATCH] Upload are deleted after decision was made in conflict activity Signed-off-by: tobiasKaminsky --- ...sResolveActivityIT_screenshotTextFiles.png | Bin 14845 -> 14670 bytes .../datamodel/UploadStorageManagerTest.java | 21 +++ .../activity/ConflictsResolveActivityIT.java | 8 +- .../datamodel/UploadsStorageManager.java | 45 ++++++- .../files/services/FileDownloader.java | 13 +- .../android/files/services/FileUploader.java | 1 + .../ui/activity/ConflictsResolveActivity.java | 122 +++++++++--------- .../android/ui/activity/FileActivity.java | 2 +- .../android/ui/adapter/UploadListAdapter.java | 1 + .../ui/dialog/ConflictsResolveDialog.java | 41 +++++- .../ui/helpers/FileOperationsHelper.java | 2 + 11 files changed, 171 insertions(+), 85 deletions(-) diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png b/screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png index 4b10461ec3cb61e741c87fc4f97ec3addcca5897..0210996fbd5fef4291d5a3c7fc70c15b2b855ca7 100644 GIT binary patch literal 14670 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 UR!t{%K*qyTRn$~~$vqDHH||gtLjV8( literal 14845 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 Bjf(&P diff --git a/src/androidTest/java/com/owncloud/android/datamodel/UploadStorageManagerTest.java b/src/androidTest/java/com/owncloud/android/datamodel/UploadStorageManagerTest.java index d8b04c5b9376..b04eeab3b67f 100644 --- a/src/androidTest/java/com/owncloud/android/datamodel/UploadStorageManagerTest.java +++ b/src/androidTest/java/com/owncloud/android/datamodel/UploadStorageManagerTest.java @@ -34,6 +34,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; /** @@ -150,6 +152,25 @@ public void corruptedUpload() { uploadsStorageManager.getAllStoredUploads(); } + @Test + public void getById() { + OCUpload upload = createUpload(account); + long id = uploadsStorageManager.storeUpload(upload); + + OCUpload newUpload = uploadsStorageManager.getUploadById(id); + + assertNotNull(newUpload); + assertEquals(upload.getLocalAction(), newUpload.getLocalAction()); + assertEquals(upload.getFolderUnlockToken(), newUpload.getFolderUnlockToken()); + } + + @Test + public void getByIdNull() { + OCUpload newUpload = uploadsStorageManager.getUploadById(-1); + + assertNull(newUpload); + } + private void insertUploads(Account account, int rowsToInsert) { for (int i = 0; i < rowsToInsert; i++) { uploadsStorageManager.storeUpload(createUpload(account)); diff --git a/src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java b/src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java index 320e2f1c9b72..b74affc0184d 100644 --- a/src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java +++ b/src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java @@ -169,7 +169,7 @@ public void cancel() { Intent intent = new Intent(targetContext, ConflictsResolveActivity.class); intent.putExtra(ConflictsResolveActivity.EXTRA_FILE, newFile); intent.putExtra(ConflictsResolveActivity.EXTRA_EXISTING_FILE, existingFile); - intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD, newUpload); + intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD_ID, newUpload.getUploadId()); ConflictsResolveActivity sut = activityRule.launchActivity(intent); @@ -210,7 +210,7 @@ public void keepExisting() { Intent intent = new Intent(targetContext, ConflictsResolveActivity.class); intent.putExtra(ConflictsResolveActivity.EXTRA_FILE, newFile); intent.putExtra(ConflictsResolveActivity.EXTRA_EXISTING_FILE, existingFile); - intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD, newUpload); + intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD_ID, newUpload.getUploadId()); ConflictsResolveActivity sut = activityRule.launchActivity(intent); @@ -256,7 +256,7 @@ public void keepNew() { Intent intent = new Intent(targetContext, ConflictsResolveActivity.class); intent.putExtra(ConflictsResolveActivity.EXTRA_FILE, newFile); intent.putExtra(ConflictsResolveActivity.EXTRA_EXISTING_FILE, existingFile); - intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD, newUpload); + intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD_ID, newUpload.getUploadId()); ConflictsResolveActivity sut = activityRule.launchActivity(intent); @@ -301,7 +301,7 @@ public void keepBoth() { Intent intent = new Intent(targetContext, ConflictsResolveActivity.class); intent.putExtra(ConflictsResolveActivity.EXTRA_FILE, newFile); intent.putExtra(ConflictsResolveActivity.EXTRA_EXISTING_FILE, existingFile); - intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD, newUpload); + intent.putExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD_ID, newUpload.getUploadId()); ConflictsResolveActivity sut = activityRule.launchActivity(intent); diff --git a/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java b/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java index c3a1796cffc4..2f1ad7b276f1 100644 --- a/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java +++ b/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java @@ -231,13 +231,27 @@ public void notifyObserversNow() { * @param upload Upload instance to remove from persisted storage. * @return true when the upload was stored and could be removed. */ - public int removeUpload(OCUpload upload) { + public int removeUpload(@Nullable OCUpload upload) { + if (upload == null) { + return 0; + } else { + return removeUpload(upload.getUploadId()); + } + } + + /** + * Remove an upload from the uploads list, known its target account and remote path. + * + * @param id to remove from persisted storage. + * @return true when the upload was stored and could be removed. + */ + public int removeUpload(long id) { int result = getDB().delete( - ProviderTableMeta.CONTENT_URI_UPLOADS, - ProviderTableMeta._ID + "=?", - new String[]{Long.toString(upload.getUploadId())} - ); - Log_OC.d(TAG, "delete returns " + result + " for upload " + upload); + ProviderTableMeta.CONTENT_URI_UPLOADS, + ProviderTableMeta._ID + "=?", + new String[]{Long.toString(id)} + ); + Log_OC.d(TAG, "delete returns " + result + " for upload with id " + id); if (result > 0) { notifyObserversNow(); } @@ -287,6 +301,25 @@ public OCUpload[] getAllStoredUploads() { return getUploads(null, (String[]) null); } + public @Nullable + OCUpload getUploadById(long id) { + OCUpload result = null; + Cursor cursor = getDB().query( + ProviderTableMeta.CONTENT_URI_UPLOADS, + null, + ProviderTableMeta._ID + "=?", + new String[]{Long.toString(id)}, + "_id ASC"); + + if (cursor != null) { + if (cursor.moveToFirst()) { + result = createOCUploadFromCursor(cursor); + } + } + Log_OC.d(TAG, "Retrieve job " + result + " for id " + id); + return result; + } + private OCUpload[] getUploads(@Nullable String selection, @Nullable String... selectionArgs) { ArrayList uploads = new ArrayList<>(); final long pageSize = 100; diff --git a/src/main/java/com/owncloud/android/files/services/FileDownloader.java b/src/main/java/com/owncloud/android/files/services/FileDownloader.java index 2c3203bd5339..b7476aa6916d 100644 --- a/src/main/java/com/owncloud/android/files/services/FileDownloader.java +++ b/src/main/java/com/owncloud/android/files/services/FileDownloader.java @@ -46,7 +46,6 @@ import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.datamodel.UploadsStorageManager; -import com.owncloud.android.db.OCUpload; import com.owncloud.android.lib.common.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; @@ -57,6 +56,7 @@ import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.operations.DownloadFileOperation; import com.owncloud.android.providers.DocumentsStorageProvider; +import com.owncloud.android.ui.activity.ConflictsResolveActivity; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.dialog.SendShareDialog; @@ -92,7 +92,6 @@ public class FileDownloader extends Service public static final String EXTRA_DOWNLOAD_RESULT = "RESULT"; public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH"; public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO"; - public static final String EXTRA_CONFLICT_UPLOAD = "CONFLICT_UPLOAD"; public static final String ACCOUNT_NAME = "ACCOUNT_NAME"; private static final int FOREGROUND_SERVICE_ID = 412; @@ -116,7 +115,7 @@ public class FileDownloader extends Service private Notification mNotification; - private OCUpload conflictUpload; + private long conflictUploadId; @Inject UserAccountManager accountManager; @Inject UploadsStorageManager uploadsStorageManager; @@ -205,7 +204,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { final String behaviour = intent.getStringExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR); String activityName = intent.getStringExtra(SendShareDialog.ACTIVITY_NAME); String packageName = intent.getStringExtra(SendShareDialog.PACKAGE_NAME); - this.conflictUpload = intent.getParcelableExtra(FileDownloader.EXTRA_CONFLICT_UPLOAD); + conflictUploadId = intent.getLongExtra(ConflictsResolveActivity.EXTRA_CONFLICT_UPLOAD_ID, -1); AbstractList requestedDownloads = new Vector(); try { DownloadFileOperation newDownload = new DownloadFileOperation(user.toPlatformAccount(), @@ -644,13 +643,13 @@ private void notifyDownloadResult(DownloadFileOperation download, // Remove success notification if (downloadResult.isSuccess()) { - if (this.conflictUpload != null) { - uploadsStorageManager.removeUpload(this.conflictUpload); + if (conflictUploadId > 0) { + uploadsStorageManager.removeUpload(conflictUploadId); } // Sleep 2 seconds, so show the notification before remove it NotificationUtils.cancelWithDelay(mNotificationManager, - R.string.downloader_download_succeeded_ticker, 2000); + R.string.downloader_download_succeeded_ticker, 2000); } } } diff --git a/src/main/java/com/owncloud/android/files/services/FileUploader.java b/src/main/java/com/owncloud/android/files/services/FileUploader.java index d89c52260a30..f2a0a0767661 100644 --- a/src/main/java/com/owncloud/android/files/services/FileUploader.java +++ b/src/main/java/com/owncloud/android/files/services/FileUploader.java @@ -808,6 +808,7 @@ private void notifyUploadResult(UploadFileOperation upload, RemoteOperationResul if (uploadResult.getCode().equals(ResultCode.SYNC_CONFLICT)) { intent = ConflictsResolveActivity.createIntent(upload.getFile(), upload.getAccount(), + upload.getOCUploadId(), Intent.FLAG_ACTIVITY_CLEAR_TOP, this); } else { diff --git a/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java b/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java index 1c3add59b6b2..61bf3b7cff27 100644 --- a/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ConflictsResolveActivity.java @@ -1,4 +1,4 @@ -/** +/* * ownCloud Android client application * * @author Bartek Przybylski @@ -54,7 +54,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict /** * A nullable upload entry that must be removed when and if the conflict is resolved. */ - public static final String EXTRA_CONFLICT_UPLOAD = "CONFLICT_UPLOAD"; + public static final String EXTRA_CONFLICT_UPLOAD_ID = "CONFLICT_UPLOAD_ID"; /** * Specify the upload local behaviour when there is no CONFLICT_UPLOAD. */ @@ -65,19 +65,24 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict @Inject UploadsStorageManager uploadsStorageManager; - private OCUpload conflictUpload; + private long conflictUploadId; private OCFile existingFile; private OCFile newFile; private int localBehaviour = FileUploader.LOCAL_BEHAVIOUR_FORGET; protected OnConflictDecisionMadeListener listener; - public static Intent createIntent(OCFile file, Account account, Integer flag, Context context) { + public static Intent createIntent(OCFile file, + Account account, + long conflictUploadId, + Integer flag, + Context context) { Intent intent = new Intent(context, ConflictsResolveActivity.class); if (flag != null) { intent.setFlags(intent.getFlags() | flag); } - intent.putExtra(ConflictsResolveActivity.EXTRA_FILE, file); - intent.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, account); + intent.putExtra(EXTRA_FILE, file); + intent.putExtra(EXTRA_ACCOUNT, account); + intent.putExtra(EXTRA_CONFLICT_UPLOAD_ID, conflictUploadId); return intent; } @@ -87,74 +92,67 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { - conflictUpload = savedInstanceState.getParcelable(EXTRA_CONFLICT_UPLOAD); + conflictUploadId = savedInstanceState.getLong(EXTRA_CONFLICT_UPLOAD_ID); existingFile = savedInstanceState.getParcelable(EXTRA_EXISTING_FILE); localBehaviour = savedInstanceState.getInt(EXTRA_LOCAL_BEHAVIOUR); } else { - conflictUpload = getIntent().getParcelableExtra(EXTRA_CONFLICT_UPLOAD); + conflictUploadId = getIntent().getLongExtra(EXTRA_CONFLICT_UPLOAD_ID, -1); existingFile = getIntent().getParcelableExtra(EXTRA_EXISTING_FILE); localBehaviour = getIntent().getIntExtra(EXTRA_LOCAL_BEHAVIOUR, localBehaviour); } - if (conflictUpload != null) { - localBehaviour = conflictUpload.getLocalAction(); + OCUpload upload = uploadsStorageManager.getUploadById(conflictUploadId); + + if (upload != null) { + localBehaviour = upload.getLocalAction(); } // new file was modified locally in file system newFile = getFile(); - listener = new OnConflictDecisionMadeListener() { - @Override - public void conflictDecisionMade(Decision decision) { - OCFile file = newFile; // local file got changed, so either upload it or replace it again by server - // version - - switch (decision) { - case CANCEL: - // nothing to do - break; - case KEEP_LOCAL: // Upload - FileUploader.uploadUpdateFile( - getBaseContext(), - getAccount(), - file, - localBehaviour, - FileUploader.NameCollisionPolicy.OVERWRITE - ); - - if (conflictUpload != null) { - uploadsStorageManager.removeUpload(conflictUpload); - } - break; - case KEEP_BOTH: // Upload - FileUploader.uploadUpdateFile( - getBaseContext(), - getAccount(), - file, - localBehaviour, - FileUploader.NameCollisionPolicy.RENAME - ); - - if (conflictUpload != null) { - uploadsStorageManager.removeUpload(conflictUpload); - } - break; - case KEEP_SERVER: // Download - if (!shouldDeleteLocal()) { - // Overwrite local file - Intent intent = new Intent(getBaseContext(), FileDownloader.class); - intent.putExtra(FileDownloader.EXTRA_USER, getUser().orElseThrow(RuntimeException::new)); - intent.putExtra(FileDownloader.EXTRA_FILE, file); - if (conflictUpload != null) { - intent.putExtra(FileDownloader.EXTRA_CONFLICT_UPLOAD, conflictUpload); - } - startService(intent); - } - break; - } - - finish(); + listener = decision -> { + OCFile file = newFile; // local file got changed, so either upload it or replace it again by server + // version + + switch (decision) { + case CANCEL: + // nothing to do + break; + case KEEP_LOCAL: // Upload + FileUploader.uploadUpdateFile( + getBaseContext(), + getAccount(), + file, + localBehaviour, + FileUploader.NameCollisionPolicy.OVERWRITE + ); + + uploadsStorageManager.removeUpload(upload); + break; + case KEEP_BOTH: // Upload + FileUploader.uploadUpdateFile( + getBaseContext(), + getAccount(), + file, + localBehaviour, + FileUploader.NameCollisionPolicy.RENAME + ); + + uploadsStorageManager.removeUpload(upload); + break; + case KEEP_SERVER: // Download + if (!shouldDeleteLocal()) { + // Overwrite local file + Intent intent = new Intent(getBaseContext(), FileDownloader.class); + intent.putExtra(FileDownloader.EXTRA_USER, getUser().orElseThrow(RuntimeException::new)); + intent.putExtra(FileDownloader.EXTRA_FILE, file); + intent.putExtra(EXTRA_CONFLICT_UPLOAD_ID, conflictUploadId); + startService(intent); + } + break; } + + finish(); }; } @@ -162,7 +160,7 @@ public void conflictDecisionMade(Decision decision) { protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putParcelable(EXTRA_CONFLICT_UPLOAD, conflictUpload); + outState.putLong(EXTRA_CONFLICT_UPLOAD_ID, conflictUploadId); outState.putParcelable(EXTRA_EXISTING_FILE, existingFile); outState.putInt(EXTRA_LOCAL_BEHAVIOUR, localBehaviour); } diff --git a/src/main/java/com/owncloud/android/ui/activity/FileActivity.java b/src/main/java/com/owncloud/android/ui/activity/FileActivity.java index 347a720cdc17..e70a7056ceee 100644 --- a/src/main/java/com/owncloud/android/ui/activity/FileActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/FileActivity.java @@ -499,7 +499,7 @@ private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation OCFile syncedFile = operation.getLocalFile(); if (!result.isSuccess()) { if (result.getCode() == ResultCode.SYNC_CONFLICT) { - Intent intent = ConflictsResolveActivity.createIntent(syncedFile, getAccount(), null, this); + Intent intent = ConflictsResolveActivity.createIntent(syncedFile, getAccount(), -1, null, this); startActivity(intent); } diff --git a/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java index 8c41e97b880f..90ec3e72200e 100755 --- a/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java @@ -573,6 +573,7 @@ private void openConflictActivity(OCFile file, OCUpload upload) { Context context = MainApp.getAppContext(); Intent intent = ConflictsResolveActivity.createIntent(file, upload.getAccount(accountManager), + upload.getUploadId(), Intent.FLAG_ACTIVITY_NEW_TASK, context); diff --git a/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java b/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java index 168b4690f510..b1a88b9915bb 100644 --- a/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java +++ b/src/main/java/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java @@ -25,6 +25,8 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; +import android.view.View; +import android.widget.Button; import android.widget.Toast; import com.nextcloud.client.account.User; @@ -47,6 +49,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; @@ -64,6 +67,7 @@ public class ConflictsResolveDialog extends DialogFragment { public OnConflictDecisionMadeListener listener; private User user; private List asyncTasks = new ArrayList<>(); + private Button positiveButton; private static final String KEY_NEW_FILE = "file"; private static final String KEY_EXISTING_FILE = "ocfile"; @@ -111,7 +115,9 @@ public void onStart() { } int color = ThemeUtils.primaryAccentColor(getContext()); - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(color); + positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + setPositiveButtonStatus(false); + alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(color); } @@ -159,9 +165,10 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { listener.conflictDecisionMade(Decision.KEEP_BOTH); } else if (binding.newCheckbox.isChecked()) { listener.conflictDecisionMade(Decision.KEEP_LOCAL); - } else { + } else if (binding.existingCheckbox.isChecked()) { listener.conflictDecisionMade(Decision.KEEP_SERVER); - } + } // else do nothing + } }) .setNegativeButton(R.string.common_cancel, (dialog, which) -> { @@ -192,12 +199,36 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { false, getContext()); - binding.newFileContainer.setOnClickListener(v -> binding.newCheckbox.setChecked(!binding.newCheckbox.isChecked())); - binding.existingFileContainer.setOnClickListener(v -> binding.existingCheckbox.setChecked(!binding.existingCheckbox.isChecked())); + View.OnClickListener checkBoxClickListener = v -> { + setPositiveButtonStatus(binding.newCheckbox.isChecked() || binding.existingCheckbox.isChecked()); + }; + + binding.newCheckbox.setOnClickListener(checkBoxClickListener); + binding.existingCheckbox.setOnClickListener(checkBoxClickListener); + + binding.newFileContainer.setOnClickListener(v -> { + binding.newCheckbox.setChecked(!binding.newCheckbox.isChecked()); + setPositiveButtonStatus(binding.newCheckbox.isChecked() || binding.existingCheckbox.isChecked()); + }); + binding.existingFileContainer.setOnClickListener(v -> { + binding.existingCheckbox.setChecked(!binding.existingCheckbox.isChecked()); + setPositiveButtonStatus(binding.newCheckbox.isChecked() || binding.existingCheckbox.isChecked()); + }); return builder.create(); } + private void setPositiveButtonStatus(boolean enabled) { + if (enabled) { + positiveButton.setTextColor(ThemeUtils.primaryAccentColor(requireContext())); + } else { + positiveButton.setTextColor(ResourcesCompat.getColor(requireContext().getResources(), + R.color.grey_200, + null)); + } + positiveButton.setEnabled(enabled); + } + public void showDialog(AppCompatActivity activity) { Fragment prev = activity.getSupportFragmentManager().findFragmentByTag("dialog"); FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); diff --git a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java index 11178e080d63..6b4a374afc71 100755 --- a/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java +++ b/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java @@ -255,6 +255,7 @@ private void syncFile(OCFile file, User user, FileDataStorageManager storageMana // this can be very intrusive; a notification should be preferred Intent intent = ConflictsResolveActivity.createIntent(file, user.toPlatformAccount(), + -1, Intent.FLAG_ACTIVITY_NEW_TASK, fileActivity); @@ -324,6 +325,7 @@ public void run() { // this can be very intrusive; a notification should be preferred Intent intent = ConflictsResolveActivity.createIntent(file, user.toPlatformAccount(), + -1, Intent.FLAG_ACTIVITY_NEW_TASK, fileActivity); fileActivity.startActivity(intent);