I am currently using AsyncTask
to download a large file in the background within my app, currently the download progress is shown as a ProgressDialog
which is updated via onProgressUpdate
as below:
protected String doInBackground(String... sUrl) {
try {
String destName = sUrl[1];
file_Delete(destName); // Just to make sure!
URL url = new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(destName);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.e(TAG, NAME + ": Error downloading file! " + e.getMessage());
return e.getMessage();
}
return null;
}
@Override protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
DownloadImage.mProgressDialog.setProgress(progress[0]);
}
This works fine, however I now want to use a notification in the notification bar so keep track of the download instead (as the file can be rather large and users would like to keep track from outside the app).
I have tried the below code however the UI starts to lag badly, I can see its due to the publishProgress
getting called alot, so how could I go about changing the background code to call publishProgress
only every second
@Override protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
DownloadImage.mProgressDialog.setProgress(progress[0]);
DownloadImage.myNotification = new NotificationCompat.Builder(c)
.setContentTitle("Downloading SlapOS")
.setContentText("Download is " + progress[0] + "% done")
.setTicker("Downloading...")
.setOngoing(true)
.setWhen(System.currentTimeMillis())
.setProgress(100, progress[0], false)
.setSmallIcon(R.drawable.icon)
.build();
DownloadImage.notificationManager.notify(1, DownloadImage.myNotification);
}
so how could I go about changing the background code to call publishProgress only every second
I have done this before for an upload function that showed the % in a Notification
, but same exact idea. Have your AsyncTask
keep track of what percentDone
the download is, and ONLY call publishProgress
when percentDone
changes. That way, you will only ever call publishProgress
when the % downloaded changes, and the Notification
therefore needs to update. This should resolve the UI lag.
I was writing this up as my suggested implementation, sounds like the OP already got it working. But maybe this will help someone else in the future:
byte data[] = new byte[1024];
long total = 0;
int count, latestPercentDone;
int percentDone = -1;
while ((count = input.read(data)) != -1) {
total += count;
latestPercentDone = (int) Math.round(total / fileLength * 100.0);
if (percentDone != latestPercentDone) {
percentDone = latestPercentDone;
publishProgress(percentDone);
}
output.write(data, 0, count);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With