diff --git a/app/src/main/java/com/simplemobiletools/filemanager/asynctasks/CopyTask.java b/app/src/main/java/com/simplemobiletools/filemanager/asynctasks/CopyTask.java new file mode 100644 index 00000000..fd26dda4 --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/filemanager/asynctasks/CopyTask.java @@ -0,0 +1,88 @@ +package com.simplemobiletools.filemanager.asynctasks; + +import android.os.AsyncTask; +import android.support.v4.util.Pair; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.ref.WeakReference; +import java.util.List; + +public class CopyTask extends AsyncTask, File>, Void, Boolean> { + private static final String TAG = CopyTask.class.getSimpleName(); + + private static WeakReference mListener; + + public CopyTask(CopyListener listener) { + mListener = new WeakReference<>(listener); + } + + @Override + protected Boolean doInBackground(Pair, File>... params) { + final Pair, File> pair = params[0]; + final List files = pair.first; + for (File file : files) { + try { + final File destinationDir = new File(pair.second, file.getName()); + copy(file, destinationDir); + return true; + } catch (Exception e) { + Log.e(TAG, "copy " + e); + } + } + return false; + } + + private void copy(File source, File destination) throws Exception { + if (source.isDirectory()) { + if (!destination.exists() && !destination.mkdirs()) { + throw new IOException("Could not create dir " + destination.getAbsolutePath()); + } + + final String[] children = source.list(); + for (String child : children) { + copy(new File(source, child), new File(destination, child)); + } + } else { + final File directory = destination.getParentFile(); + if (directory != null && !directory.exists() && !directory.mkdirs()) { + throw new IOException("Could not create dir " + directory.getAbsolutePath()); + } + + final InputStream in = new FileInputStream(source); + final OutputStream out = new FileOutputStream(destination); + + final byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + } + } + + @Override + protected void onPostExecute(Boolean success) { + final CopyListener listener = mListener.get(); + if (listener == null) + return; + + if (success) { + listener.copySucceeded(); + } else { + listener.copyFailed(); + } + } + + public interface CopyListener { + void copySucceeded(); + + void copyFailed(); + } +} diff --git a/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java b/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java index 51965f40..0e9012f1 100644 --- a/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java +++ b/app/src/main/java/com/simplemobiletools/filemanager/fragments/ItemsFragment.java @@ -10,6 +10,7 @@ import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; +import android.support.v4.util.Pair; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AlertDialog; import android.util.SparseBooleanArray; @@ -33,6 +34,7 @@ import com.simplemobiletools.filemanager.Constants; import com.simplemobiletools.filemanager.R; import com.simplemobiletools.filemanager.Utils; import com.simplemobiletools.filemanager.adapters.ItemsAdapter; +import com.simplemobiletools.filemanager.asynctasks.CopyTask; import com.simplemobiletools.filemanager.models.FileDirItem; import java.io.File; @@ -48,7 +50,7 @@ import butterknife.OnClick; public class ItemsFragment extends android.support.v4.app.Fragment implements AdapterView.OnItemClickListener, SwipeRefreshLayout.OnRefreshListener, ListView.MultiChoiceModeListener, - ListView.OnTouchListener { + ListView.OnTouchListener, CopyTask.CopyListener { @BindView(R.id.items_list) ListView mListView; @BindView(R.id.items_swipe_refresh) SwipeRefreshLayout mSwipeRefreshLayout; @BindView(R.id.items_holder) CoordinatorLayout mCoordinatorLayout; @@ -59,6 +61,7 @@ public class ItemsFragment extends android.support.v4.app.Fragment private String mPath; private String mCopyDestinationPath; private Snackbar mSnackbar; + private AlertDialog mCopyDialog; private boolean mShowHidden; private int mSelectedItemsCnt; @@ -388,9 +391,9 @@ public class ItemsFragment extends android.support.v4.app.Fragment builder.setPositiveButton("OK", null); builder.setNegativeButton("Cancel", null); - final AlertDialog alertDialog = builder.create(); - alertDialog.show(); - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + mCopyDialog = builder.create(); + mCopyDialog.show(); + mCopyDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final File destinationDir = new File(destination.getText().toString().trim()); @@ -399,7 +402,7 @@ public class ItemsFragment extends android.support.v4.app.Fragment return; } - List itemsToCopy = new ArrayList<>(itemIndexes.size()); + final List itemsToCopy = new ArrayList<>(itemIndexes.size()); for (Integer i : itemIndexes) { FileDirItem item = mItems.get(i); itemsToCopy.add(new File(item.getPath())); @@ -407,19 +410,21 @@ public class ItemsFragment extends android.support.v4.app.Fragment final RadioGroup radio = (RadioGroup) copyView.findViewById(R.id.dialog_radio_group); if (radio.getCheckedRadioButtonId() == R.id.dialog_radio_copy) { - + Utils.showToast(getContext(), R.string.copying); + final Pair, File> pair = new Pair<>(itemsToCopy, destinationDir); + new CopyTask(ItemsFragment.this).execute(pair); } else { for (File f : itemsToCopy) { f.renameTo(new File(destinationDir, f.getName())); } - alertDialog.dismiss(); + mCopyDialog.dismiss(); fillItems(); } } }); - alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + mCopyDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { mCopyDestinationPath = mPath; @@ -571,6 +576,17 @@ public class ItemsFragment extends android.support.v4.app.Fragment mSelectedItemsCnt = 0; } + @Override + public void copySucceeded() { + mCopyDialog.dismiss(); + fillItems(); + } + + @Override + public void copyFailed() { + Utils.showToast(getContext(), R.string.copy_failed); + } + public interface ItemInteractionListener { void itemClicked(String path); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7c82ddd4..622f2074 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,6 +21,8 @@ Destination Select destination Could not write to the selected destination + Could not copy the files + Copying 1 item deleted