Add progress bar to backup - java

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;
}

Related

How to detect uris from moved files

Anyone knows how to detect uris from moved files programmatically in Java/Android?When I start the app I detect all images in my phone (with their uris, path....), if I move the images with a media manager, next time I start the app I can get the whole uris again, with the new path. But, if I move these images programmatically (copying the image and deleting the image from the original path) next time I start the app the uris will be the previous path a not the new one. I'm trying to fix deleting the app cache, but doesn't work. Anyone knows what can be happen?
I tried to move the files with two functions and I have same problem:
public static void moveFile(ArrayList<ImagesData> images) throws IOException {
for (int i = 0; i < images.size(); i++) {
File file_Source = new File(images.get(i).imagePath);
File file_Destination = new File(Environment.getExternalStorageDirectory() + "/PrivateGallery/" + new File(images.get(i).imagePath).getName());
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(file_Source).getChannel();
destination = new FileOutputStream(file_Destination).getChannel();
Log.i(TAG, "Source " + source + " destination " + destination);
long count = 0;
long size = source.size();
while((count += destination.transferFrom(source, count, size-count)) < size);
//destination.transferFrom(source, 0, source.size());
file_Source.delete();
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
}
public void changeToNewPath(ArrayList<ImagesData> images) {
String outputPath = Environment.getExternalStorageDirectory() + "/PrivateGallery/";
//TODO COMPROBAR SI EXISTE YA UN ARCHIVO CON SU NOMBRE
InputStream in = null;
OutputStream out = null;
for(int i = 0; i < images.size(); i++) {
try { //TODO revisar lod el cambio de directorio
//create output directory if it doesn't exist
//File dir = new File(outputPath);
File f = new File(images.get(i).imagePath);
String a = f.getName();
Log.e(TAG, a);
in = new FileInputStream(images.get(i).imagePath);
out = new FileOutputStream(outputPath + new File(images.get(i).imagePath).getName());
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file
out.flush();
out.close();
out = null;
// delete the original file
new File(images.get(i).imagePath).delete();
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}

Copy directory files into subfolder

i want to copy files from parent directory into subfolder in parent directory. Now i get the copied files into subfolder, but it repeated itself everytime if i get already the subfolder and files copied, it makes it all time repeatedly, i want it to male only one time
public static void main(String[] args) throws IOException {
File source = new File(path2);
File target = new File("Test/subfolder");
copyDirectory(source, target);
}
public static void copyDirectory(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < children.length; i++) {
copyDirectory(new File(sourceLocation, children[i]), new File(
targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
byte[] buf = new byte[1];
int length;
while ((length = in.read(buf)) > 0) {
out.write(buf, 0, length);
}
in.close();
out.close();
}
}
You program have problem in following line
String[] children = sourceLocation.list();
Lets suppose your parent dir = Test
So the following code will create a sub-folder under test
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
And after that you are retrieving the children of source folder as your destination is already created it will also be counted as child of source folder and recursively get copied. So you need to retrieve children first and then create the target directory So that target directory would not be count in copy process.
Change your code as follows.
public static void main(String[] args) throws IOException {
File source = new File("Test");
File target = new File("Test/subfolder");
copyDirectory(source, target);
}
public static void copyDirectory(File sourceLocation, File targetLocation)
throws IOException {
String[] children = sourceLocation.list();
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
for (int i = 0; i < children.length; i++) {
copyDirectory(new File(sourceLocation, children[i]), new File(
targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
byte[] buf = new byte[1];
int length;
while ((length = in.read(buf)) > 0) {
out.write(buf, 0, length);
}
in.close();
out.close();
}
}
You are calling your method recursively without a condition to break the recursion. You will have to exclude directories in your for-loop.

Saving sharedPreference file

I successfully saved preferences in SharedPreferences. How can I save the preference file in sdcard and vice-versa ??? {I want to give option to the user to backup, so that he can save and load preferences across re-intallations}
To store the sharedpreference in the sdcard you can try
private void backup(Context context) {
File root = context.getFilesDir();
File parent = root.getParentFile();
File[] files = parent.listFiles();
File[] tmp = null;
for (File file : files) {
if (file.isDirectory()) {
tmp = file.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.getName().contains("your_shared_preference_file_name");
}
});
if (tmp != null && tmp.length == 1) {
break;
}
}
}
File file = null;
if (tmp.length == 1) {
parent = tmp[0].getParentFile();
file = new File(Environment.getExternalStorageDirectory(), "tmp.xml");
FileInputStream fis = new FileInputStream(tmp[0]);
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[32768];
int count = 0;
while ((count = fis.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fis.close();
fos.flush();
fos.close();
}
}
Finally got time to finish the project
Since I used one preference file to save the user data, this is the code that I used to copy it.
File fileSrc = new File(filePath, "userdata.xml");
File fileDes = new File("/data/data/com.nik/shared_prefs/", "userdata.xml");
...
...
private void copyFileToShared(File fileSrc, File fileDes) {
FileInputStream fileinputstream=null;
FileOutputStream fileoutputstream=null;
try {
fileinputstream = new FileInputStream(fileSrc);
fileoutputstream = new FileOutputStream(fileDes);
byte[] buffer = new byte[4096];
int count = 0;
while ((count = fileinputstream.read(buffer)) > 0) {
fileoutputstream.write(buffer, 0, count);
}
fileinputstream.close();
fileoutputstream.flush();
fileoutputstream.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
And the file is copied... :-)

How can i copy the entire directory?

I want copy entire directory onClick in android.. How can i do it?
I have:
String sdCard = Environment.getExternalStorageDirectory().toString();
File srcFolder = new File(sdCard +"tryFirstFolder");
File destFolder = new File(sdCard +"/TryFolder");
And then i need the code to copy the entire content of srcFolder to destFolder
you can copy directory from one location to other using this:
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
also this link will help you to copy or move files from one folder to other:
http://www.codeofaninja.com/2013/04/copy-or-move-file-from-one-directory-to.html

Copy directory - Working out progress

I have a routine which i've been using for a while to copy a directory from an SD card to a plugged in USB drive. It works, but as there can be 3000 photos, i'm sure you get that it an get a bit slow. So i'm trying to implement some sort of update progress bar.
Here is my code that does the copying;
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");
}
}
I assume that I need to check how big the directory is before starting so i've added:
public static int CountFilesInDirectory(String location) {
File f = new File(location);
int count = 0;
for (File file : f.listFiles()) {
if (file.isFile()) {
count++;
}
}
return count;
}
But I guess, I can't work out how to put A and B together. I can't work out how to increment in the right place for the update. - I could be on the completely wrong path! Any tips really would be appreciated.
http://labs.makemachine.net/2010/05/android-asynctask-example/
see the above link async task loading concept will help you

Categories