How to check if file is existing AND has the same content - android

I'm having trouble of looking for a way to know whether a file exists, if it does, does it have the same content? If yes then don't download, otherwise download the file.
In my code, I need to download the PDF file before viewing it. I have already the checking if file exists, but it checks only the filename (this one I'm not sure of). Does the File class' exists() method only check for filename? If it does, how do I know if it has different content?
Here's my code:
class DownloadFileTask extends AsyncTask<String, String, String> {
private Context context;
public ProgressDialog pDialog;
private File pdfFile = new File(Environment
.getExternalStorageDirectory().getPath()
+ "/SAMPLE/"
+ pdfFileName);
public DownloadFileTask(Context context) {
this.context = context;
}
/**
* Before starting background thread Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
if (!pdfFile.exists()) {
pDialog = new ProgressDialog(context);
pDialog.setMessage(getString(R.string.loading));
pDialog.setCancelable(false);
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.show();
}
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... path) {
int count;
if (!pdfFile.exists()) {
if (Utility.isNetworkAvailable(parentActivityContext)) {
try {
String urlLastPath = Utility
.getLastPathFromUrl(path[0]);
String urlEncoded = URLEncoder.encode(urlLastPath,
"utf-8");
String urlDecoded = null;
String urlStr;
if (urlEncoded.contains(" ")) {
urlDecoded = urlEncoded.replaceAll(" ", "%20");
urlStr = SystemInfo.getResourceUrl() + "pdf/"
+ urlDecoded;
} else if (urlEncoded.contains("+")) {
urlDecoded = urlEncoded.replaceAll(
Pattern.quote("+"), "%20");
urlStr = SystemInfo.getResourceUrl() + "pdf/"
+ urlDecoded;
} else {
urlStr = SystemInfo.getResourceUrl() + "pdf/"
+ urlEncoded;
}
URL url = new URL(urlStr);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
// getting file length
int lengthOfFile = urlConnection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(
url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().getPath()
+ "/'SAMPLE/" + pdfFileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""
+ (int) ((total * 100) / lengthOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
Log.e("Error: ", e.getMessage());
}
} else {
openDialog(getString(R.string.error),
getString(R.string.internet_connection_error));
}
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
/** PDF reader code */
Intent intent = new Intent(parentActivityContext,
MuPDFActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.fromFile(pdfFile));
startActivity(intent);
}
}

Its always a good idea to validate a file's MD5 checksum before and after you download it (and after placing it on your /sdcard). Proper implementation at server side makes sure that the MD5 sums for the files hosted there are published. Verifying the MD5 sum of the file that you've downloaded ensures that you have a full, complete, and uncorrupted version of the file.
In your case, you can compare the MD5 checksum of the File_1 after downloading and storing it on sd-card with the MD5 checksum of File_2 before downloading.

Related

Download Multiple Files Using Async

I am trying to download multiple files using asyc but for some reason it only downloads one file successfully while all the other files are 0 bytes.
Only the file that is added first to the string array is downloaded successfully, the rest are written as 0 bytes on the SD card.
class DownloadFileFromFTP extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
//showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
//code
//Read SharedPref
String str_dirRestoredImage_open = sharedPref.getString("SharedPref_dirRestoredImage_open", "");
int count;
OutputStream output = null;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(), 8192);
int totalFilesChecked = arrListStr_Files_Checked.size();
for (int i=0;i<totalFilesChecked;i++)
{
// Output stream
file_name_remote_abs = stringArr_Files_Checked[i];
file_name_remote = file_name_remote_abs.substring(file_name_remote_abs.lastIndexOf('/') + 1);
output = new FileOutputStream(str_dirRestoredImage_open+"/"+file_name_remote);
Log.d("LOG", "zzz_i: "+i +" :"+file_name_remote);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
// Stuff that updates the UI
Toast.makeText(getApplicationContext(), "File Restored: "+file_name_remote, Toast.LENGTH_LONG).show();
}
});
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
// Stuff that updates the UI
Toast.makeText(getApplicationContext(), "Failed To Restore: "+file_name_remote, Toast.LENGTH_LONG).show();
}
});
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
//pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
//dismissDialog(progress_bar_type);
}
}
This is how I am calling it, where stringArr_Files_Checked is a string array of absolute URLs of files.
new DownloadFileFromFTP().execute(stringArr_Files_Checked);

Delete file if AsyncTask Fail

Currently
I am downloading a file from a URL, I'm doing this within AsyncTask inside a Adapter. The problem I have is that when I press back onBackPressed the download stops but the file remains in the folder FileOutputStream(Environment.getExternalStorageDirectory().toString()+"/file.mp4");
My Question
Is it possible to delete the file if AsyncTask does not complete?
I have tried to do file.delete(); in the catch of doinbackground but I get error file.delete(); is ignored
Here is a summary of my adapter----
When Item in holder is clicked I call AsyncTask:
holder.setItemClickListener(new ItemClickListener() {
if (pos == 1) {
if(manager.fetchVideoPath(pos)==null) {
DownloadFileFromURL p = new DownloadFileFromURL();
p.execute(pos + "", "https://www.dropbox.com/s/xnzw753f13k68z4/Piper%20First%20Look%20%282016%29%20-%20Pixar%20Animated%20Short%20HD.mp4?dl=1");
a = "one";
bars.set(pos,new ProgressModel(pos,1));
//This is what is causing the issue
RecyclerVideoAdapter.this.notifyItemChanged(pos);
}
My AsyncTask:
private class DownloadFileFromURL extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
((CircularProgressBar)vview.findViewById(R.id.circularProgressBar)).setProgress(1);
}
#Override
protected String doInBackground(String... f_url) {
int count;
String pathreference = f_url[0]+",";
positionnumber = Integer.parseInt(f_url[0]);
try {
URL url = new URL(f_url[1]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
if (a.equals("one")) {
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/file.mp4");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
pathreference = pathreference+Environment.getExternalStorageDirectory().toString()+"/file.mp4";
output.close();
input.close();
}
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return pathreference;
}
protected void onProgressUpdate(String... progress) {
bars.get(positionnumber).setProgress_(Float.parseFloat(progress[0]));
((CircularProgressBar)vview.findViewById(R.id.circularProgressBar)).setProgress(bars.get(positionnumber).getProgress_());
}
#Override
protected void onPostExecute(String file_url) {
String []split = file_url.split(",");
int index1 = Integer.parseInt(split[0]);
videoHolderClass.set(index1,new VideoHolderClass(index1,imgres[0]));
bars.get(index1).setProgress_(0);
manager.insertVideoPath(index1+"",split[1]);
RecyclerVideoAdapter.this.notifyItemChanged(index1);
}
}
Building on the answer on this post, try to put the logic of deleting the file inside isCancelled() like this:
if (isCancelled() && file.exists())
file.delete();
else
{
// do your work here
}
Then you can call p.cancel(true) inside onBackPressed

Same file with same name getting downloaded even when provided with different URLs

I have a activity that contains a listview and sends different url when different list item is clicked via intent in onitemclicklistener
In the singleitemview activity which is opened when list item is clicked i have a button to download images
The problem is only 1 image is getting downloaded even different URLs are provided through different list item clicks
I think this is happening because of providing only 1 outputstream like this
OutputStream output = new FileOutputStream("/sdcard/download/loadedfile.png");
how to change this so each different image gets downloaded with its own file name
onitemclicklistener of listview
public void onItemClick(AdapterView<?> p1, View view, int position, long p4)
{
Intent intent = new Intent(ProActivity.this, SingleItemView.class);
intent.putExtra("download",
(codelist.get(position).getDownloadCode()));
staetActivity(intent);
}
My download class
class DownloadFileFromURL extends AsyncTask<String, String, String>
{
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
try{
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream
OutputStream output = new FileOutputStream("/sdcard/download/loadedfile.png");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""+(int)((total*100)/lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
//e.printStackTrace();
Log.e("Error: ","Error Message ::" + e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String downurl) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
Toast.makeText(SingleItemView.this,
getString(R.string.download_complete),
Toast.LENGTH_SHORT).show();
}
}
1
onclick method for my download button in singlitemview activity
Intent i = getIntent();
file_url = i.getStringExtra("download");
public void downloadnow(){
// different url is recived from different list item click via intent
String downurl = file_url;
new DownloadFileFromURL().execute(downurl);
}
Try to change file name loadedfile.png to downloaded file name.
Something like:
String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );
OutputStream output = new FileOutputStream("/sdcard/download/" + filename);

Android: How to create a direct download link in android

Can anyone give me an idea on how to create a textview which has a link and when the user click it, the file from that link will be automatically downloaded by the device
EDIT:
here's the code were working on:
String link = "http://www.exampleurl.com/"+pref.getString("fsfile" + count, null);
link = link.replaceAll(" ", "%20");
fsfile.setText("Attached File");
fsfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// starting new Async Task
new DownloadFileFromURL().execute(link);
}
});
but it seems the String link is not identified inside the .setOnClickListener
Thats quite easy
http://developer.android.com/reference/android/app/DownloadManager.html
Example: http://androidtrainningcenter.blogspot.co.at/2013/05/android-download-manager-example.html
And start this method after clicking the textview (Catch with Handler or listener)
/**
* Start Download
*/
public void startDownload() {
DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Request mRqRequest = new Request(
Uri.parse("http://androidtrainningcenter.blogspot.in/2012/11/android-webview-loading-custom-html-and.html"));
mRqRequest.setDescription("This is Test File");
// mRqRequest.setDestinationUri(Uri.parse("give your local path"));
long idDownLoad=mManager.enqueue(mRqRequest);
}
But be sure you are min. on API 9
Please use the below code onclick of TextView:
<Your TextView>.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// starting new Async Task
new DownloadFileFromURL().execute(<Your URL String>);
}
});
DownloadFromURL.java
public class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""+(int)((total*100)/lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
// Displaying downloaded image into image view
// Reading image path from sdcard
String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
// setting downloaded into image view
my_image.setImageDrawable(Drawable.createFromPath(imagePath));
}
}

Handling exception when trying to download file from url with async in android

I am using a AsyncTask to download a file from a URL in Android.
This is the class to download the file in the background:
//-----------------------------ASYNC DOWNLOADER--------------------------------
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
//TODO Zustzinfos für alle Methoden hinzufügen
/**
* This method is called for executing the background task in the AsyncTask.
* For this tutorial we are only sleeping the thread for the number of
* seconds passed as parameter of the function.
*
* #param numSeconds: life of the task
* #return the result of the background task
*/
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/"+Name+".xml");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""+(int)((total*100)/lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("ASYNC",e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#SuppressWarnings("deprecation")
#Override
protected void onPostExecute(String error) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
String xmlPath = Environment.getExternalStorageDirectory().toString() + "/"+Name+".xml";
Log.d("XMLDOWNLOADPATH", xmlPath);
Log.d("DOWNLOADXML","End Download XML file");
}
}
I want to be able to recognize in my main activity (the async class is a inner class of the main acticity) if there was a exception and show the error message in a Dialog or Toast.
I tried to return the value from doInBackground() to onPostExecute() and write this String to a global String variable like this:
protected String doInBackground(String... f_url) {
String error = null;
try {
}
catch(Exception e){
error = e.toString();
}
return error;
#Override
protected void onPostExecute(String error) {
globalStringvariable = error;
}
But this does not work properly, the dialog does not always show the exception message. Is this the best way to realize my problem?
e.getMessage();
That's what you're looking for.
Also note that if your getting null, it can be because you are catching Exception as a generic, you should always try to catch a specific Exception in order to get the message back.

Categories

Resources