I implemented multiple download by following this answer here in stackoverflow. But I faced the following issue:
==> When downloading more than one file, the progress of files gets mixed i.e if 1st file is downloaded 1.15mb/5mb and 2nd is downloaded 5mb/10mb then the notification for 1st file shows "Downloaded 1.15/5mb" and "Downloaded 5/10mb" alternatively. Same is for other files. So my question is How to show correct progress based on the size of file itself?
Also the filenames gets mixed after the download is commpleted i.e it shows "File Downloaded: 1st.pdf" in notification for both downloads.
Here is my DownloadService.class:
public class DownloadService extends Service {
final static String TAG = DownloadService.class.getSimpleName();
String downloadUrl, saveName;
int id;
public DownloadService() {
super();
}
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
private float totalFileSize;
public static boolean isDownloading = false;
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
downloadUrl = intent.getStringExtra("downloadurl");
saveName = intent.getStringExtra("savename");
id = intent.getIntExtra("id", 0);
HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
return START_STICKY;
}
private void isDownloading(boolean b, int id) {
this.id = id;
isDownloading = b;
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "onHandleIntent: ");
//SHOW NOTIFICATION IN WHILE RUNNING BACKGROUND SERVICES
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.logout)
.setContentTitle("Dishanirdesh-Plus")
.setContentText("Downloading: " + saveName)
.setOngoing(true)
.setAutoCancel(true);
notificationManager.notify(id, notificationBuilder.build());
initDownload(downloadUrl, id);
}
}
private void initDownload(String downloadUrl, int id) {
Log.d(TAG, "initDownload: ");
SetupRetrofit setupRetrofit = new SetupRetrofit();
Retrofit retrofit = setupRetrofit.getRetrofit();
DownloadApiInterface retrofitInterface = retrofit.create(DownloadApiInterface.class);
Call<ResponseBody> request = retrofitInterface.downloadFile(downloadUrl);
try {
downloadFile(request.execute().body(), id);
isDownloading(true, id);
} catch (IOException e) {
e.printStackTrace();
isDownloading(false, id);
notificationManager.cancel(id);
Toast.makeText(getApplicationContext(),LinkConfig.BOOK_ERROR_MSG, Toast.LENGTH_SHORT).show();
}
}
private void downloadFile(ResponseBody body, int id) throws IOException {
Log.d(TAG, "downloadFile: ");
int count;
byte data[] = new byte[1024 * 4];
long fileSize = body.contentLength();
InputStream bis = new BufferedInputStream(body.byteStream(), 1024 * 8);
String bookPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +
LinkConfig.DISHANIRDESH_PLUS_FOLDER_NAME + "/" + LinkConfig.BOOK_SUB_FOLDER_NAME + "/" + saveName;
File outputFile = new File(bookPath);
OutputStream output = new FileOutputStream(outputFile);
long total = 0;
long startTime = System.currentTimeMillis();
int timeCount = 1;
while ((count = bis.read(data)) != -1) {
total += count;
//Converting byte to mega-byte
totalFileSize = (float) (fileSize / (Math.pow(1024, 2)));//shows in MB
double current = (total / (Math.pow(1024, 2)));
int progress = (int) ((total * 100) / fileSize);
long currentTime = System.currentTimeMillis() - startTime;
Download download = new Download();
download.setTotalFileSize(totalFileSize);
Log.d(TAG, "downloadFile: totalFileSize: " + totalFileSize);
if (currentTime > 10 * timeCount) {
download.setCurrentFileSize((float) current);
download.setProgress(progress);
sendNotification(download, id);
timeCount++;
}
output.write(data, 0, count);
}
output.flush();
output.close();
bis.close();
Encryption encryption = new Encryption();
Log.d(TAG, "downloadFile: encryption");
try {
try {
encryption.encrypt(bookPath);
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
onDownloadComplete(id);
}
private void sendNotification(Download download, int id) {
Log.d(TAG, "sendNotification: ");
//Send to EbookDetailActivity
sendIntent(download, id);
//Send to Notification Bar
notificationBuilder.setProgress(100, download.getProgress(), false);
notificationBuilder.setContentText("Downloading file " +new DecimalFormat("##.##").format(download.getCurrentFileSize()) +"/" +new DecimalFormat("##.##").format(totalFileSize)+"MB");
notificationManager.notify(id, notificationBuilder.build());
}
private void sendIntent(Download download, int id) {
Log.d(TAG, "sendIntent: ");
Intent intent = new Intent(EbookDetailActivity.MESSAGE_PROGRESS);
intent.putExtra("download", download);
intent.putExtra("id", id);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
private void onDownloadComplete(int id) {
Log.d(TAG, "onDownloadComplete: ");
isDownloading(false, id);
try {
Download download = new Download();
download.setProgress(100);
sendIntent(download, id);
notificationManager.cancel(id);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder .setContentText("Tap to Open");
notificationManager.notify(id, notificationBuilder.build());
Intent intent = new Intent(this, EbookDetailActivity.class);
intent.putExtra("savename", saveName);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder
.setAutoCancel(true)
.setContentIntent(pIntent)
.setContentTitle("File Downloaded: " + saveName);
notificationManager.notify(id, notificationBuilder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
notificationManager.cancel(id);
}