Alternative way to show download progress of DownloadManager - android

I'm trying to show the download progress of DownloadManager in percentage as shown in the notification bar.
I've read up some answer here.
However, the method provided is using the Thread.
As my understanding,Thread is not a good way.
Is there any alternative way to do the same thing?
Or using Thread is just fine in this case?
Edit 1:
Added in the code in my project.
new Thread(new Runnable() {
#Override
public void run() {
boolean downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
((Activity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
holder.mTextView.setText(String.valueOf(dl_progress) + "%");
}
});
cursor.close();
}
}
}).start();

Related

Why does Environment.getExternalStorageDirectory() create direcotory in Cache folder

When I use Environment.getExternalStorageDirectory()+File.separator+"applicationAsbid"; I expect to create a directory in device's external storage but it is created in Cache folder.
Why?
What happened and what should I do?
UPDATE:
This is my method:
root = Environment.getExternalStorageDirectory().getPath();
myDir = new File(root);
myDir.mkdir();
private void downloadDoc(ProgressBar progressBar, CircularImageView imageView, String name, String link, SendMessageViewModel messageData) {
progressBar.setVisibility(View.VISIBLE);
Uri uri = Uri.parse(link);
DownloadManager downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("در حال دانلود");
request.setDescription("لطفا منتظر بمانید...");
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
request.setDestinationInExternalFilesDir(mContext, root, name);
final long id = downloadManager.enqueue(request);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(id);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
long downloadedBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
long totalBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
final int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
final int percent = (int) ((downloadedBytes * 100) / totalBytes);
((Activity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
progressBar.setProgress(percent);
if (percent == 100) {
Toast.makeText(mContext, "دانلود با موفقیت انجام شد", Toast.LENGTH_SHORT).show();
timer.purge();
timer.cancel();
for (int item : downloadList) {
if (Integer.parseInt(messageData.getId()) == item) {
imageView.setImageResource(R.drawable.ic_doc3);
imageView.setContentDescription("after");
progressBar.setVisibility(View.GONE);
}
}
}
}
});
}
}
}, 0, 100);
}
At the end I should say this is not my own code and my colleague has written that. We check that and found nothing so I aske here.
We use Downloadmanager in another class and for download something else. That works fine but here it does not work.
Second Update:
I changed my code to this:
root = Environment.getExternalStorageDirectory().getPath() + "/Dehkade/Chat1";
myDir = new File(root);
if (!myDir.exists()) {
if (!myDir.mkdir()) {
Toast.makeText(mContext," ...sorry could not create directory...",Toast.LENGTH_SHORT).show();
return;
}
}
But it does not work too, in fact the Toast is executed. Also I use this code:
request.setDestinationInExternalFilesDir(mContext, null, name);
Instead of this code:
request.setDestinationInExternalFilesDir(mContext, root, name);
But nothing changes.

showing download progress in progress bar using DownloadManager

I am working on an android app in which i am using DownloadManager to download a file from a server.
Problem
While the file download is in progress, I want to show the download progress via progress bar. File is downloaded successfully but I am not able to show the download progress.
Code I use to show progress
private void startAppDownload() {
...
// code to show download progress
new Thread(new Runnable() {
#Override
public void run() {
boolean isDownloading = true;
int downloadStatus, totalBytesDownloaded, totalBytes;
DownloadManager.Query downloadQuery = new DownloadManager.Query();
downloadQuery.setFilterById(downloadID);
Cursor cursor = downloadManager.query(downloadQuery);
cursor.moveToFirst();
while (isDownloading) {
totalBytesDownloaded = cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
);
totalBytes = cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
);
downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if(downloadStatus == DownloadManager.STATUS_SUCCESSFUL) {
isDownloading = false;
}
final int downloadProgress = (int) ((double)totalBytesDownloaded / (double)totalBytes * 100f);
runOnUiThread(new Runnable() {
#Override
public void run() {
downloadProgressBar.setProgress(downloadProgress);
}
});
}
cursor.close();
}
}).start();
}
I logged the totalBytesDownloaded variable but it is always zero and the totalBytes variable is always -1.
This causes downloadProgress variable to always be zero, hence progress bar shows no progress.
Question
What am I doing wrong here? Why is totalBytesDownloaded variable always equal to zero and totalBytes variable always -1?
You have a Logic error, Your Query is out of the while loop where the UI is updated
private void startAppDownload() {
new Thread(new Runnable() {
#Override
public void run() {
boolean isDownloading = true;
int downloadStatus, totalBytesDownloaded, totalBytes;
while (isDownloading) {
DownloadManager.Query downloadQuery = new DownloadManager.Query();
downloadQuery.setFilterById(downloadID);
Cursor cursor = downloadManager.query(downloadQuery);
cursor.moveToFirst();
totalBytesDownloaded = cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
);
totalBytes = cursor.getInt(
cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
);
downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if(downloadStatus == DownloadManager.STATUS_SUCCESSFUL) {
isDownloading = false;
break;;
}
final int downloadProgress = (int) ((double)totalBytesDownloaded / (double)totalBytes * 100f);
runOnUiThread(new Runnable() {
#Override
public void run() {
downloadProgressBar.setProgress(downloadProgress);
}
});
}
cursor.close();
}
}).start();
}

DownloadManager.remove(download_id) crash app

I am trying to cancel downloading task with id.
I get id from
DownloadManager manager = (DownloadManager) getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
downloadId = manager.enqueue(req);
I want to stop download when on user button click, but I tested to stop download after 10% of being downloaded in this test code.
the code "manager.remove(downloadId);" is working perfect to clear downloading noti and stopping the task with requested ID. But it also stop the app too, app error also occur after that code. please how can I solve the problem.
new Thread(new Runnable() {
#Override
public void run() {
boolean downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
cursor = manager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
final int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
String finalDl_size;
int dl_size = (int) (bytes_total/(1024*1024));
finalDl_size = Integer.toString(dl_size)+" MB";
if(dl_size>1000){dl_size=(int) (bytes_total/(1024*1024*1024));
finalDl_size = Integer.toString(dl_size)+" GB";}
final String finalDl_size1 = finalDl_size;
runOnUiThread(new Runnable() {
#Override
public void run() {
btndownload.setText("Downloading "+Integer.toString(dl_progress)+"% , "+ finalDl_size1);
if(dl_progress==100){
btndownload.setBackgroundColor(Color.GREEN);
btndownload.setText("Download Completed");
}
else if(dl_progress>10){
try{
manager.remove(downloadId); ///// Stop after 10%
}
catch (Exception e){}
}
}
});
cursor.close();
}
}
}).start();
Logcat Output
Please Kindly help me. Thank you in advance.
Try this
if (cursor.getCount() > 0)
manager.remove(downloadId); ///// Stop after 10%

how to pause downloadmanager in android

The question is I have implemented android downloadmanager to download files from internet. how can i pause and resume the download? i have read lots of posts and searched google but could not find a working answer. Thanks
DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(url + fileName));
downloadRequest.setTitle("Downloading: ");
downloadRequest.setDescription("Description");
downloadRequest.allowScanningByMediaScanner();
downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,applicationApk);
manager = (DownloadManager) downloadActivity.getSystemService(Context.DOWNLOAD_SERVICE);
downloadId = manager.enqueue(downloadRequest);
new Thread(new Runnable()
{
#Override
public void run()
{
int fileSize = size;
downloadProgress.setProgress(0);
downloadProgress.setMax(fileSize);
sizeInBytes = fileSize * 1024 * 1024;
DownloadManager.Query q = new DownloadManager.Query();
//q.setFilterById(downloadId);
downloading = true;
while (downloading)
{
Cursor cursor = manager.query(q);
if (cursor.moveToFirst())
{
int sizeIndex = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
int downloadedIndex = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
long size = cursor.getInt(sizeIndex);
long downloaded = cursor.getInt(downloadedIndex);
if (size != -1) dl_progress = downloaded * fileSize / size;
}
downloadProgress.setProgress((int) dl_progress);
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL)
{
downloading = false;
}
cursor.close();
}
}
}).start();

How to Show download progress in progress bar in Android?

I am using .net web services and I am able to download the file in sd card, But I want to show progress bar when particular file start download and complete and then I want to show options like view and cancel.
Click event Class:
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
LazyAdapter ca = (LazyAdapter)parent.getAdapter();
FolderList item_name = (FolderList)ca.getItem(position);
FolderList DocumentID = (FolderList)ca.getItem(position);
FolderList type = (FolderList)ca.getItem(position);
Intent mIntent = new Intent();
mIntent.putExtra("item_name", item_name.folder_name);
mIntent.putExtra("item_id", DocumentID.ID);
mIntent.putExtra("item_type", type.type);
mIntent.getStringExtra("item_name");
String Type = mIntent.getStringExtra("item_type");
Log.i("Type", Type);
if {
// Some code here...
} else {
Intent i = new Intent(getApplicationContext(), Display_image.class);
i.putExtra("item_name", item_name.folder_name);
i.putExtra("ID", DocumentID.ID);
i.putExtra("item_type", type.type);
i.putExtra("User_ID",User_ID);
i.getStringExtra("item_name");
Id = i.getStringExtra("ID");
i.getStringExtra("item_type");
startActivity(i);
}
}
My Code: I want to use download manager
SoapPrimitive DocumentResponse = (SoapPrimitive)Envelope.getResponse();
Log.i("DocumentResponse", DocumentResponse.toString());
String DocAsString = DocumentResponse.toString();
byte[] decodedString = Base64.decode(DocAsString, Base64.DEFAULT);
File direct = new File(Environment.getExternalStorageDirectory() + "/MyFolder");
if(!direct.exists())
{
direct.mkdir();
}
File photo = new File(Environment.getExternalStorageDirectory() + "/MyFolder", Name);
if (photo.exists())
{
photo.delete();
}
try {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(Name));
request.setDescription("Have Fun ;)");
request.setTitle("Downloading...");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(decodedString);
fos.close();
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
ContentValues values= new ContentValues();
System.out.println(values);
}
catch (java.io.IOException e)
{
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
Please suggest how to use download manager into it??? thanks
You could use a ProgressBar to accomplish this.
First, add a progressbar to your interface like this:
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#android:style/Widget.ProgressBar.Small"/>
Then in your code update your method like this:
protected ProgressBar mProgressBar;
protected long downloadId;
protected DownloadManager manager;
public void startdownload() {
//<SET UP DOWNLOAD MANAGER HERE>
downloadId = manager.enqueue(request);
mProgressBar = findViewById(R.id.progress_bar);
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = manager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
cursor.close();
int dl_progress = (bytesDownloaded * 1f / bytesTotal) * 100;
runOnUiThread(new Runnable(){
#Override
public void run(){
mProgressbar.setProgress((int) dl_progress);
}
});
}
}, 0, 10);
}
Use Follow Method
private NotificationManager mNotifyManager;
case R.id.btnSubmit:
mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("BuyMixTapes")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.appiconmain);
new DownloadFile().execute(vv);
public class DownloadFile extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
//context.showDialog(progress_bar_type);
mBuilder.setProgress(100, 0, false);
mNotifyManager.notify(id, mBuilder.build());
}
protected String doInBackground(String... f_url) {
int count;
try {
for (int i = 0; i < f_url.length; i++) {
Log.e("0url",""+f_url[0]);
Log.e("1url",""+f_url[1]);
// Log.e("1url",""+f_url[1]);
URL url = new URL(f_url[i]);
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/"+f_url[i]);
OutputStream output = new FileOutputStream(
"/sdcard/" +i + "buymix.mp3");
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
*/
/**
* After completing background task
* Dismiss the progress dialog
**/
#Override
protected void onProgressUpdate(String... values) {
// Update progress
mBuilder.setProgress(100, Integer.parseInt(values[0]), false);
mNotifyManager.notify(id, mBuilder.build());
super.onProgressUpdate(values);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
mBuilder.setContentText("Download complete");
// Removes the progress bar
String imagePath = Environment.getExternalStorageDirectory()
.toString() + "/downloaded.mp3";
mBuilder.setProgress(0, 0, false);
mNotifyManager.notify(id, mBuilder.build());
}
}
Update 2021:
Add a ProgressBar in your layout (TextView is just for showing more information):
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/progressBar"
android:text="Hello World!" />
Then before onCreate:
DownloadManager downloadManager;
long downloadReference;
TextView text1;
ProgressBar progressBar;
Timer progressTimer;
Afterwards, in onCreate:
text1 = (TextView) findViewById(R.id.textView1);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
Then after setting up download manager:
// <Some codes which setup download manager>
downloadReference = downloadManager.enqueue(request); // enqueue a new download
// update progressbar
progressTimer = new Timer();
progressTimer.schedule(new TimerTask() {
#Override
public void run() {
DownloadManager.Query downloadQuery = new DownloadManager.Query();
downloadQuery.setFilterById(downloadReference);
Cursor cursor = downloadManager.query(downloadQuery);
if (cursor.moveToFirst()) { // this "if" is crucial to prevent a kind of error
final int downloadedBytes = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
final int totalBytes = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); // integer is enough for files under 2GB
cursor.close();
final float downloadProgress = downloadedBytes * 100f / totalBytes;
if(downloadProgress > 99.9) // stop repeating timer (it's also useful for error prevention)
progressTimer.cancel();
runOnUiThread(new Runnable() {
#Override
public void run() {
text1.setText(downloadedBytes + "\n" + totalBytes + "\n" + downloadProgress + "%");
progressBar.setProgress((int) downloadProgress);
}
});
}
}
}, 0, 1000);
Some tips:
If your file is larger than 2GB, you should use another type instead of int such as double etc.
You can stop timer somewhere else for example, in BroadcastReceiver if you have.
Task executions is every 1000 milliseconds (every 1 second) which is obviously changable.

Categories

Resources