package com.openfarmanager.android.filesystem.actions; import android.content.Context; import com.openfarmanager.android.model.TaskStatusEnum; import com.openfarmanager.android.model.exeptions.SdcardPermissionException; import com.openfarmanager.android.utils.FileUtilsExt; import com.openfarmanager.android.utils.StorageUtils; import com.openfarmanager.android.utils.SystemUtils; import org.apache.commons.io.FileExistsException; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import static com.openfarmanager.android.model.TaskStatusEnum.*; import static com.openfarmanager.android.utils.StorageUtils.checkForPermissionAndGetBaseUri; import static com.openfarmanager.android.utils.StorageUtils.checkUseStorageApi; /** * author: vnamashko */ public class MoveTask extends FileActionTask { protected File mDestinationFolder; protected String mDestinationFileName; public MoveTask(Context context, int invokedOnPanel, List<File> items, File destination, String destinationFileName) { super(context, invokedOnPanel, items); mDestinationFolder = destination; mDestinationFileName = destinationFileName; } @Override protected TaskStatusEnum doInBackground(Void... voids) { if (mItems.size() < 1) { return OK; } File srcFile = mItems.get(0); // first file from src folder boolean theSameFolders = FileUtilsExt.isTheSameFolders(mItems, mDestinationFolder); if (mItems.size() == 1 && theSameFolders) { // move inside the same folder, perform rename if (mDestinationFileName == null || mDestinationFileName.trim().equals("")) { return ERROR_WRONG_DESTINATION_FILE_NAME; } return new RenameTask(srcFile, mDestinationFileName).execute(); } else if (theSameFolders) { return OK; } mSdCardPath = SystemUtils.getExternalStorage(mDestinationFolder.getAbsolutePath()); mUseStorageApi = checkUseStorageApi(mSdCardPath); try { if (mUseStorageApi) { mBaseUri = checkForPermissionAndGetBaseUri(); } } catch (SdcardPermissionException e) { return ERROR_STORAGE_PERMISSION_REQUIRED; } // TODO: temporary List<File> items = new ArrayList<>(mItems); for (File file : items) { try { mDoneSize += FileUtils.sizeOf(file); if (mUseStorageApi) { moveOnSdcard(file, mDestinationFolder); } else if (!mDestinationFolder.canWrite() || !file.getParentFile().canWrite()) { if (!RootTask.move(file, mDestinationFolder)) { throw new IOException("Cannot move file to " + mDestinationFolder.getAbsolutePath()); } } else { FileUtils.moveToDirectory(file, mDestinationFolder, false); } updateProgress(); } catch (NullPointerException e) { return ERROR_FILE_NOT_EXISTS; } catch (FileExistsException e) { return ERROR_FILE_EXISTS; } catch (IllegalArgumentException e) { return ERROR_MOVE_FILE; } catch (IOException e) { return ERROR_MOVE_FILE; } } return OK; } private void moveOnSdcard(File source, File destination) throws IOException { if (source.isDirectory()) { File destinationFolder = new File(destination, source.getName()); StorageUtils.mkDir(mBaseUri, mSdCardPath, destinationFolder); for (File child : source.listFiles()) { moveOnSdcard(child, destinationFolder); } } else { moveFileRoutine(mSdCardPath, source, destination); } String path = SystemUtils.getExternalStorage(source.getAbsolutePath()); if (StorageUtils.checkUseStorageApi(path)) { StorageUtils.delete(mBaseUri, mSdCardPath, source.getAbsolutePath()); } else { source.delete(); } } private void moveFileRoutine(String sdCardPath, File source, File destination) throws IOException { OutputStream out = StorageUtils.getStorageOutputFileStream( new File(destination, source.getName()), mBaseUri, sdCardPath); int len; InputStream in = new FileInputStream(source); while ((len = in.read(BUFFER)) > 0) { out.write(BUFFER, 0, len); } in.close(); out.close(); } }