I currently have an asynctask
which downloads a mp3 from a server. When the user starts to download it, a status bar notification is created. This displays the prog
I had similar issue once, I solved it using CountDownTimer.
Similar to how @superfell suggested, you can call progress update of AsyncTask regularly while downloading file. And call the Notification Manager only at specific interval.
After calling start()
of CountDownTimer, it will call onTick()
function after every fixed interval of time, and will call onFinish()
either when timer is timed out or when called explicitly. cancel()
function will only cancel the timer and will not call onFinish()
method.
class DownloadMaterial extends AsyncTask {
CountDownTimer cdt;
int id = i;
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
@Override
protected void onPreExecute() {
/**
* Create custom Count Down Timer
*/
cdt = new CountDownTimer(100 * 60 * 1000, 500) {
public void onTick(long millisUntilFinished) {
mNotifyManager.notify(id, mBuilder.build());
}
public void onFinish() {
mNotifyManager.notify(id, mBuilder.build());
}
};
}
@Override
protected String doInBackground(String... strings) {
/**
* Start timer to update Notification
* Set Progress to 20 after connection
* Build Notification
* Increment Progress
* Download and Save file
*/
try {
mNotifyManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Downloading File")
.setContentText(file_name)
.setProgress(0, 100, false)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(Notification.PRIORITY_LOW);
// Initialize Objects here
publishProgress("5");
mNotifyManager.notify(id, mBuilder.build());
cdt.start();
// Create connection here
publishProgress("20");
// Download file here
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) (20 + (total * 80 / fileLength)));
output.write(data, 0, count);
}
} catch (Exception e) {
return "Failed";
}
return "Success";
}
@Override
protected void onProgressUpdate(String... values) {
/**
* Update Download Progress
*/
mBuilder.setContentInfo(values[0] + "%")
.setProgress(100, Integer.parseInt(values[0]), false);
}
@Override
protected void onPostExecute(String s) {
String title;
if (s.equals("Success")) {
title = "Downloaded";
} else {
title = "Error Occurred";
}
mBuilder.setContentTitle(title)
.setContentInfo("")
.setOngoing(false)
.setProgress(0, 0, false);
cdt.onFinish();
cdt.cancel();
}
}
It is a good practice to call onFinish()
first and then call cancel()
.