com.osama.cryptofm.tasks.MoveTask.java Source code

Java tutorial

Introduction

Here is the source code for com.osama.cryptofm.tasks.MoveTask.java

Source

/*
 * Copyright (c) 2017. Osama Bin Omar
 *    This file is part of Crypto File Manager also known as Crypto FM
 *
 *     Crypto File Manager is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Crypto File Manager 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 Crypto File Manager.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package com.osama.cryptofm.tasks;

import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.provider.DocumentFile;
import android.util.Log;
import android.widget.Toast;

import com.osama.cryptofm.CryptoFM;
import com.osama.cryptofm.filemanager.listview.FileListAdapter;
import com.osama.cryptofm.filemanager.utils.SharedData;
import com.osama.cryptofm.filemanager.utils.UiUtils;
import com.osama.cryptofm.utils.FileDocumentUtils;
import com.osama.cryptofm.utils.FileUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.util.ArrayList;

/**
 * Created by tripleheader on 12/26/16.
 * File moving task
 */

public class MoveTask extends AsyncTask<String, String, String> {
    private Context mContext;
    private static final String TAG = MoveTask.class.getName();
    private MyProgressDialog mProgressDialog;
    private ArrayList<String> mFiles;
    private String mDestinationFolder;
    private boolean isNextFile = true;
    private String originalDestination;
    private FileListAdapter mAdapter;
    private DocumentFile rootDocumentFile;

    public MoveTask(Context context, ArrayList<String> files, String destination, FileListAdapter mAdapter) {
        this.mContext = context;
        mProgressDialog = new MyProgressDialog(mContext, "Copying", this);
        this.mFiles = files;
        this.mDestinationFolder = destination;
        this.originalDestination = destination;
        this.mAdapter = mAdapter;
    }

    @Override
    protected String doInBackground(String... strings) {
        String sourcePath = null;
        if (mDestinationFolder.contains(mFiles.get(0))) {
            sourcePath = null;
            //check if user pasting in the folder it has selected to copy or more haha
            for (String s : mFiles) {
                if (mDestinationFolder.equals(s + "/")) {
                    sourcePath = s;
                    break;
                }
            }
        }
        //remove the destination folder from selected list if its there
        if (sourcePath != null) {
            mFiles.remove(sourcePath);
        }
        for (String source : mFiles) {
            try {
                //check if destination folder is same as source

                mDestinationFolder = originalDestination;
                File temp = TasksFileUtils.getFile(source);
                Log.d(TAG, "doInBackground: source path is: " + source);
                if (FileUtils.isDocumentFile(source)) {
                    rootDocumentFile = FileDocumentUtils.getDocumentFile(new File(mDestinationFolder));
                    moveDocumentFile(FileDocumentUtils.getDocumentFile(temp));
                } else {
                    if (FileUtils.isDocumentFile(mDestinationFolder)) {
                        rootDocumentFile = FileDocumentUtils.getDocumentFile(new File(mDestinationFolder));
                    }
                    move(temp);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                return "failed";

            }
        }
        return "success";
    }

    private void move(File f) throws Exception {
        if (f.isDirectory()) {
            //check if destination folder is in external sdcard
            if (FileUtils.isDocumentFile(mDestinationFolder)) {
                DocumentFile rootDocumentFile = FileDocumentUtils.getDocumentFile(new File(mDestinationFolder));
                rootDocumentFile.createDirectory(f.getName());
            } else {
                //create folder in the destination
                mDestinationFolder = mDestinationFolder + f.getName() + "/";

                File tmp = new File(mDestinationFolder);
                if (!tmp.exists()) {
                    tmp.mkdir();
                } else {
                    return;
                }

            }
            Log.d(TAG, "move: File is a directory");
            for (File file : f.listFiles()) {
                move(file);
            }
        } else {
            Log.d(TAG, "move: Moving file: " + f.getName());
            Log.d(TAG, "move: Destination folder is: " + mDestinationFolder);
            isNextFile = true;
            publishProgress(f.getName());
            publishProgress("" + 0);
            if (FileUtils.isDocumentFile(mDestinationFolder)) {
                DocumentFile dest = rootDocumentFile.createFile(FileUtils.getExtension(f.getName()), f.getName());
                innerMove(new BufferedInputStream(new FileInputStream(f)),
                        CryptoFM.getContext().getContentResolver().openOutputStream(dest.getUri()), f.length());
            } else {
                //check if file already exits
                File destinationFile = new File(mDestinationFolder + f.getName());
                if (destinationFile.exists()) {
                    return;
                }

                innerMove(new BufferedInputStream(new FileInputStream(f)),
                        new BufferedOutputStream(new FileOutputStream(destinationFile)), f.length());
            }
        }

        //delete the input file
        //if copying then don't
        if (SharedData.IS_COPYING_NOT_MOVING) {
            return;
        }
        if (!f.delete()) {
            throw new IOException("cannot move files");
        }
    }

    private void innerMove(InputStream in, OutputStream out, long totalFileLength) throws Exception {

        byte[] data = new byte[2048];
        int start = 0;
        long readData = 0;
        isNextFile = false;
        double progress;

        while ((start = in.read(data)) > 0) {
            out.write(data, 0, start);
            readData += start;
            progress = (double) readData / (double) totalFileLength;
            if (mProgressDialog.isInNotifyMode()) {
                mProgressDialog.setProgress((int) (progress * 100));
            } else {
                publishProgress("" + (int) (progress * 100));
            }

        }
        out.flush();

        in.close();
        out.close();
    }

    @Override
    protected void onProgressUpdate(String... values) {
        try {
            int progress = Integer.valueOf(values[0]);
            mProgressDialog.setProgress(progress);
        } catch (NumberFormatException e) {
            mProgressDialog.setMessage(values[0]);
        }
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        mProgressDialog.dismiss(s);
        Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
        UiUtils.reloadData(mContext, mAdapter);

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog.setMessage("Moving file");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    private void moveDocumentFile(DocumentFile file) throws Exception {
        if (file.isDirectory()) {
            Log.d(TAG, "moveDocumentFile: Yes document file is directory");
            //change the destination folder
            mDestinationFolder = mDestinationFolder + file.getName() + "/";
            //check if destination folder is not document file
            if (FileUtils.isDocumentFile(mDestinationFolder)) {
                rootDocumentFile = rootDocumentFile.createDirectory(file.getName());
            } else {
                File tmp = new File(mDestinationFolder);
                if (!tmp.exists()) {
                    tmp.mkdir();
                } else {
                    return;
                }
            }
            for (DocumentFile f : file.listFiles()) {
                moveDocumentFile(f);
            }
        } else {
            isNextFile = true;
            publishProgress(file.getName());
            publishProgress("" + 0);
            //check if pasting in internal storage
            if (!FileUtils.isDocumentFile(mDestinationFolder)) {
                Log.d(TAG, "moveDocumentFile: moving document file in internal storage");
                File destinationFile = new File(mDestinationFolder + file.getName());
                innerMove(CryptoFM.getContext().getContentResolver().openInputStream(file.getUri()),
                        new BufferedOutputStream(new FileOutputStream(destinationFile)), file.length());
            } else {
                Log.d(TAG, "moveDocumentFile: Moving document file honey");
                DocumentFile destFile = rootDocumentFile.createFile(file.getType(), file.getName());

                innerMove(CryptoFM.getContext().getContentResolver().openInputStream(file.getUri()),
                        CryptoFM.getContext().getContentResolver().openOutputStream(destFile.getUri()),
                        file.length());
            }
        }

        //delete the input file
        //if copying then don't
        if (SharedData.IS_COPYING_NOT_MOVING) {
            return;
        }
        if (!file.delete()) {
            throw new IOException("cannot move files");
        }
    }

}