简体   繁体   中英

Add progress bar to backup

I'm using the following code to create a backup of a folder structure on my app (backing up to remote USB)

It works fine, however now i'm trying to work out how to give an indication of how the current percentage of how it's going etc. Realistically, I guess I don't understand how the copy works enough to list how many files there are in the folders to work out a percentage? Or what to increment.

Any tips really will be appreciated.

Here is my backup code:

 public void doBackup(View view) throws IOException{

        Time today = new Time(Time.getCurrentTimezone());
        today.setToNow();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        final String curDate = sdf.format(new Date());

        final ProgressDialog pd = new ProgressDialog(this);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMessage("Running backup. Do not unplug drive");
        pd.setIndeterminate(true);
        pd.setCancelable(false);
        pd.show();
        Thread mThread = new Thread() {
        @Override
        public void run() {
        File source = new File(Global.SDcard); 
        File dest = new File(Global.BackupDir + curDate);
        try {
            copyDirectory(source, dest);
        } catch (IOException e) {

            e.printStackTrace();
        }
        pd.dismiss();


        }
        };
        mThread.start();

    }

    public void copyDirectory(File sourceLocation , File targetLocation)
            throws IOException {

                Log.e("Backup", "Starting backup");
                if (sourceLocation.isDirectory()) {
                    if (!targetLocation.exists() && !targetLocation.mkdirs()) {
                        throw new IOException("Cannot create dir " + targetLocation.getAbsolutePath());
                    }

                    String[] children = sourceLocation.list();
                    for (int i=0; i<children.length; i++) {
                        copyDirectory(new File(sourceLocation, children[i]),
                                new File(targetLocation, children[i]));
                    }
                } else {

                    Log.e("Backup", "Creating backup directory");
                    File directory = targetLocation.getParentFile();
                    if (directory != null && !directory.exists() && !directory.mkdirs()) {
                        throw new IOException("Cannot create dir " + directory.getAbsolutePath());
                    }

                    InputStream in = new FileInputStream(sourceLocation);
                    OutputStream out = new FileOutputStream(targetLocation);

                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                    in.close();
                    out.close();
                    Log.e("Backup", "Finished");
                }
            }

You could call the following function on the top-most File to get the total size its contents...

long getFileSize(File aFile) {

    //Function passed a single file, return the file's length.
    if(!aFile.isDirectory())
        return aFile.length();

    //Function passed a directory.
    // Sum and return the size of the directory's contents, including subfolders.
    long netSize = 0;
    File[] files = aFile.listFiles();
    for (File f : files) {
        if (f.isDirectory())
            netSize += getFileSize(f);
        else
            netSize += f.length();
    }
    return netSize;
}

and then keep track of the total size of the files which have been copied. Using SizeOfCopiedFiles/SizeOfDirectory should give you a rough progress estimate.

Edit: Updating the progress bar...

The following loop seems like a good place to do updates...

while ((len = in.read(buf)) > 0) {
    out.write(buf, 0, len);
    sizeOfCopiedFiles += len;
    pd.setProgress((float)SizeOfCopiedFiles/SizeOfDirectory);
}

(Note, I'm assuming there is pd.setProgress(float f) that takes a value from 0 to 1.)

To do this your copyDirectory(...) would need to take in a reference to your ProgressDialog, it would also need to take SizeOfCopiedFiles (for the sum of file writes from previous calls) and SizeOfDirectory. The function would need to return an updated value for sizeOfCopiedFiles to reflect the updated value after each recursive call.

In the end, you'd have something like this... (Note: Pseudocode for clarity)

public long copyDirectory(File source, File target, long sizeOfCopiedFiles,
        long sizeOfDirectory, ProgressDialog pd) {

    if (source.isDirectory()) {
        for (int i = 0; i < children.length; i++) {
            sizeOfCopiedFiles = copyDirectory(sourceChild, destChild,
                    sizeOfCopiedFiles, sizeOfDirectory, pd);
        }
    } else {
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
            sizeOfCopiedFiles += len;
            pd.setProgress((float)sizeOfCopiedFiles / sizeOfDirectory);
        }

    }
    return sizeOfCopiedFiles;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM