I want to download some files from url to refresh my app but I don´t know what is the best way to do this. I have this code to download one file but when I download more than one sometimes gives me an error. Is it possible to do the download in background without using Android Activity? Thank you
class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Error en la descarga: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"Programa actualizado correctamente", Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
fOut = openFileOutput("example.json",MODE_PRIVATE);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
fOut.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (fOut != null)
fOut.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
}
and I call to this task with:
downloadTask.execute("myurl");
private class DownloadAsynkTask extends AsyncTask<String, Void, Integer> {
#Override
protected void onPreExecute() {
// progress dialog
}
#Override
protected Integer doInBackground(String... urls) {
HttpURLConnection connection = null;
InputStream is = null;
for (int i=0; i< urls.length; i++) {
try {
URL url = new URL(urls[i]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return connection.getResponseCode();
} else {
is = connection.getInputStream();
}
// do something whit url data (add it to list maybe)
if (connection != null) {
connection.disconnect();
}
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
// OK
} else {
}
}
}
and call it whit String[] urls
new DownloadAsynkTask().execute(urls);
Related
I have an online music player in which I dedicated a button in order to download the file. There's a "progressDialog" which works fine and shows progress of downloading file and it seems that it's really downloading my file. But after completion there's no folder nor file on my device.
I also added Write External Storage permission in my manifest.
Here's my download class:
public class DownloadTask extends AsyncTask<String, Integer, String> {
#SuppressLint("StaticFieldLeak")
private Context context;
public static ProgressDialog progressBar;
public DownloadTask(Context context) {
this.context = context;
progressBar = new ProgressDialog(context);
progressBar.setMessage("Downloading...");
progressBar.setIndeterminate(true);
progressBar.setCancelable(true);
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.show();
}
#Override
protected String doInBackground(String... strings) {
InputStream inputStream = null;
OutputStream outputStream = null;
HttpURLConnection connection = null;
try {
URL url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
inputStream = connection.getInputStream();
fileCache();
outputStream = new FileOutputStream(context.getFilesDir() + "listening"
+ strings[1] + ".mp3");
byte[] data = new byte[4096];
long total = 0;
int count;
while ((count = inputStream.read(data)) != -1) {
total += count;
if (fileLength > 0)
publishProgress((int) (total * 100 / fileLength));
outputStream.write(data, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setIndeterminate(false);
progressBar.setMax(100);
progressBar.setProgress(values[0]);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressBar.dismiss();
if (s != null) {
Toast.makeText(context, "Error while Downloading", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Downloaded successfully", Toast.LENGTH_SHORT).show();
}
}
private void fileCache() {
File myDir = new File(context.getFilesDir(), "listening");
if (!myDir.exists()) {
myDir.mkdirs();
}
}
}
And here's my button's function:
DownloadTask downloadTask = new DownloadTask(context);
downloadTask.execute(extra.getString("link"), extra.getString("title"));
I have created an async task to download a .csv file from a webserver. Unfortunately the file is stored in the right directory, but it's empty.
This is my async task
public class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private ProgressDialog prgDialog = null;
private PowerManager.WakeLock mWakeLock;
private String fileName;
public DownloadTask(Context context, String fileName) {
this.context = context;
this.fileName = fileName;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
/* Take CPU lock to prevent CPU from going off if the user
presses the power button during download */
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
mWakeLock.acquire();
prgDialog = new ProgressDialog(context);
prgDialog.setMessage(context.getString(R.string.prgDialogMessage));
prgDialog.setCancelable(false); // Not able to cancel until programmatically called
prgDialog.show();
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
/* Expect HTTP 200 OK, to make sure the app doesn't mistakenly save an error report
instead of the file */
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return R.string.errorServer + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// Download the file
input = connection.getInputStream();
// Get dynamic storage directory
File myFile= new File(Environment.getExternalStorageDirectory(), fileName);
output = new FileOutputStream(myFile);
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
if (prgDialog != null) {
if (prgDialog.isShowing()) {
prgDialog.dismiss();
}
prgDialog = null;
}
if (result != null) {
Toast.makeText(context,R.string.errorDownload + result, Toast.LENGTH_LONG).show();
}
}
}
I don't get any error messages or exceptions, so I don't know where the problem is. I consign the URL with the execute() function of the async task.
Thanks for helping me!
My app is a media player, it plays media by downloading the appropriate files from the Internet. I am using AsyncTask to do this, however the task takes longer to execute when multiple files need to be downloaded which results in a media player delay.
The desired behavior is to start playing a file after it has been downloaded while continuing to download any other files.
My code is as follows:
public class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
private String folder;
private ProgressDialog mProgressDialog;
private int noOfURLs;
private int noUrlLoad;
public DownloadTask(Context context, String folder, ProgressDialog mProgressDialog) {
this.context = context;
this.folder = folder;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
noOfURLs = sUrl.length;
for (int i = 0; i < sUrl.length; i++) {
URL url = new URL(sUrl[i]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Máy chủ trả về HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + folder + "/File" + (i + 1) + "." + sUrl[i].charAt(sUrl[i].length() - 3) + sUrl[i].charAt(sUrl[i].length() - 2) + sUrl[i].charAt(sUrl[i].length() - 1));
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
noUrlLoad++;
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context, context.getString(R.string.error) + result, Toast.LENGTH_LONG).show();
}
}
Inside your doInBackground method, call publishProgress(Integer) to send your updates to the UI thread. This will trigger the onProgressUpdate method to be called, and you'll be able to see when the first download has finished.
http://developer.android.com/reference/android/os/AsyncTask.html#publishProgress(Progress...)
I want to implement autoupdate for my app.
I used the DownloadManager (and now an AsyncTask for download) and install the file.
The download is working fine. On the PostExecute I fire an intent to install the new apk. Everytime i got a parsing error.
When I open the file in ES File Explorer, I am able to install it successfully, but not within the app and the intent.
I even changed from /Android/data/packagename/files to /Download but still not working.
PS: i know the code is dirty, but working, and I changed so often so many thinks to get it work, but it doesnt...
public class UpdateAsyncTask extends AsyncTask<String, Integer, String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(LoginActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
protected String doInBackground(String... arg0) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
//URL url = new URL(arg0[0]);
URL url = new URL(apkUrl);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
//output = new FileOutputStream(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "Straffv2.apk");
output = new FileOutputStream("/storage/emulated/0/Download/Straffv2.apk");
File outputFile = new File(Environment.DIRECTORY_DOWNLOADS, "Straffv2.apk");
outputFile.setReadable(true, false);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
protected void onPostExecute(String result){
mProgressDialog.dismiss();
if (result != null) {
//Toast.makeText(LoginActivity.this,"Download error: "+result, Toast.LENGTH_LONG).show();
}
else {
//Toast.makeText(LoginActivity.this,"File downloaded", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.DIRECTORY_DOWNLOADS, "Straffv2.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
LoginActivity.this.startActivity(intent);
}
}
}
I'm downloading a file from a server and for some reason i can't determine, the downloaded file size doesn't match the original file size. Here's my code.
private class dl extends AsyncTask<String,Integer,Void>
{
int size;
#Override
protected Void doInBackground(String... arg0) {
// TODO Auto-generated method stub
try{
URL myFileUrl = new URL("http://10.0.2.2:8080/testdlapps/chrome-beta.zip");
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setConnectTimeout(5000);
conn.connect();
InputStream is = conn.getInputStream();
size = conn.getContentLength();
Log.v("INFO---------------------", "size is " +size);
FileOutputStream fout1 = new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+"xyz.zip");
BufferedOutputStream bos = new BufferedOutputStream(fout1);
byte[] b = new byte[1024]; int i=0, count=0;
while((count = is.read(b)) != -1)
{
bos.write(b,0,count);
i+=count;
publishProgress(i);
Log.v("INFO----------------------------",""+count);
}
fout1.close();
}catch(Exception e){
Log.v("INFO--------------------------","Error!!");
Log.v("INFO--------------------------",e.getMessage());
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
tv.setText("downloaded " + progress[0] + "/" + size ); //tv is a TextView
}
}
When i run the app, after the download completes, count and size are the same but the actual file size i.e /mnt/sdcard/xyz.zip is always less than size. Any ideas what going wrong?
override onPostExecute and check if actually it finishes, perhaps here a code to download with resume support,
pay attention because if you press back the download may still run:
if (isCancelled())
return false;
in the loop is needed because the close() on the socket will hang on exit without you noticeing it
here is the code:
class DownloaderTask extends AsyncTask<String, Integer, Boolean>
{
private ProgressDialog mProgress;
private Context mContext;
private Long mFileSize;
private Long mDownloaded;
private String mDestFile;
public DownloaderTask(Context context, String path)
{
mContext = context;
mFileSize = 1L;
mDownloaded = 0L;
mDestFile = path;
}
#Override
protected void onPreExecute()
{
mProgress = new ProgressDialog(mContext);
mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgress.setMessage("Downloading...");
mProgress.setCancelable(true);
mProgress.setCanceledOnTouchOutside(false);
mProgress.setOnCancelListener(new DialogInterface.OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
DownloaderTask.this.cancel(true);
}
});
mProgress.show();
}
#Override
protected void onProgressUpdate(Integer... percent)
{
mProgress.setProgress(percent[0]);
}
#Override
protected Boolean doInBackground(String... urls)
{
FileOutputStream fos = null;
BufferedInputStream in = null;
BufferedOutputStream out = null;
AndroidHttpClient mClient = AndroidHttpClient.newInstance("AndroidDownloader");
try
{
HttpResponse response = null;
HttpHead head = new HttpHead(urls[0]);
response = mClient.execute(head);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
return false;
Boolean resumable = response.getLastHeader("Accept-Ranges").getValue().equals("bytes");
File file = new File(mDestFile);
mFileSize = (long) Integer.parseInt(response.getLastHeader("Content-Length").getValue());
mDownloaded = file.length();
if (!resumable || (mDownloaded >= mFileSize))
{
Log.e(TAG, "Invalid size / Non resumable - removing file");
file.delete();
mDownloaded = 0L;
}
HttpGet get = new HttpGet(urls[0]);
if (mDownloaded > 0)
{
Log.i(TAG, "Resume download from " + mDownloaded);
get.setHeader("Range", "bytes=" + mDownloaded + "-");
}
response = mClient.execute(get);
if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_PARTIAL_CONTENT))
return false;
if (mDownloaded > 0)
publishProgress((int) ((mDownloaded / mFileSize) * 100));
in = new BufferedInputStream(response.getEntity().getContent());
fos = new FileOutputStream(file, true);
out = new BufferedOutputStream(fos);
byte[] buffer = new byte[8192];
int n = 0;
while ((n = in.read(buffer, 0, buffer.length)) != -1)
{
if (isCancelled())
return false;
out.write(buffer, 0, n);
mDownloaded += n;
publishProgress((int) ((mDownloaded / (float) mFileSize) * 100));
}
} catch (Exception e)
{
e.printStackTrace();
return false;
} finally
{
try
{
mClient.close();
if (in != null)
in.close();
if (out != null)
out.close();
if (fos != null)
fos.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return true;
}
#Override
protected void onCancelled()
{
finish();
}
#Override
protected void onPostExecute(Boolean result)
{
if (mProgress.isShowing())
mProgress.dismiss();
if (result)
// done
else
// error
}
}
If it is a chunked response, the content-length in the header will be a guess at best.