Search code examples
androidfirebase-storageandroid-download-manager

Using ProgressBar with DownloadManager


In my app, I use DownloadManager to download a file from Firebase.

import static android.os.Environment.DIRECTORY_DOWNLOADS;

public class Physics extends AppCompatActivity {
PDFView pdfView;
FirebaseStorage firebaseStorage;
StorageReference storageReference;
StorageReference ref;
File file;
File files;
ProgressBar progressBar;
private Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    setContentView(R.layout.activity_physics1);

    pdfView = findViewById(R.id.pdfview);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);


    Context mContext = getApplicationContext();
    String path = mContext.getFilesDir().getAbsolutePath() + "/storage/emulated/0/Android/data/com.impwala.impwala/files/Download/asd.nomedia";
    File file = new File("/storage/emulated/0/Android/data/com.impwala.impwala/files/Download/asd.nomedia");

    if (file.exists()) {
        files = new File("/storage/emulated/0/Android/data/com.impwala.impwala/files/Download/asd.nomedia");
        pdfView.fromFile(files).load();
    } else {
        if (haveNetwork()) {
            download();
        } else if (!haveNetwork()) {
            final Intent mainIntent = new Intent(Physics.this, Nointernet.class);
            Physics.this.startActivity(mainIntent);
            Physics.this.finish();
        }
    }
}

// Indicate that we would like to update download progress
private static final int UPDATE_DOWNLOAD_PROGRESS = 1;

// Use a background thread to check the progress of downloading
private final ExecutorService executor = Executors.newFixedThreadPool(1);

// Use a hander to update progress bar on the main thread
private final Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
    @Override
    public boolean handleMessage(@NonNull Message msg) {
        if (msg.what == UPDATE_DOWNLOAD_PROGRESS) {
            int downloadProgress = msg.arg1;

            // Update your progress bar here.
            progressBar.setProgress(downloadProgress);

        }
        return true;
    }

});

public boolean haveNetwork () {
    boolean have_WIFI = false;
    boolean have_MobileData = false;

    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
    NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();

    for (NetworkInfo info : networkInfos) {
        if (info.getTypeName().equalsIgnoreCase("WIFI"))
            if (info.isConnected())
                have_WIFI = true;
        if (info.getTypeName().equalsIgnoreCase("MOBILE"))
            if (info.isConnected())
                have_MobileData = true;
    }
    return have_MobileData || have_WIFI;
}

public void download () {

    storageReference = FirebaseStorage.getInstance().getReference();
    ref = storageReference.child("asd.pdf");

    ref.getDownloadUrl()
            .addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    String url = uri.toString();
                    downloadFile(Physics.this, "asd", ".nomedia", DIRECTORY_DOWNLOADS, url); // Successfully downloaded data to local file
                    // ...
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    // Handle failed download
                    // ...
                }
            });
}

public void downloadFile (Context context, String fileName, String fileExtension, String destinationDirectory, String url)
    {
        final DownloadManager downloadManager = (DownloadManager) context.
                getSystemService(Context.DOWNLOAD_SERVICE);

    Uri uri = Uri.parse(url);
    DownloadManager.Request request = new DownloadManager.Request(uri);
  request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalFilesDir(context, destinationDirectory, fileName + fileExtension);

      final long downloadId = downloadManager.enqueue(request);
    //Run a task in a background thread to check download progress
    executor.execute(new Runnable() {
        @Override
        public void run() {
            int progress = 0;
            boolean isDownloadFinished = false;
            while (!isDownloadFinished) {
                Cursor cursor = downloadManager.query(new DownloadManager.Query().setFilterById(downloadId));
                if (cursor.moveToFirst()) {
                    int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                    switch (downloadStatus) {
                        case DownloadManager.STATUS_RUNNING:
                            long totalBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                            if (totalBytes > 0) {
                                long downloadedBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                                progress = (int) (downloadedBytes * 100 / totalBytes);
                            }

                            break;
                        case DownloadManager.STATUS_SUCCESSFUL:
                            progress = 100;
                            isDownloadFinished = true;
                            break;
                        case DownloadManager.STATUS_PAUSED:
                        case DownloadManager.STATUS_PENDING:
                            break;
                        case DownloadManager.STATUS_FAILED:
                            isDownloadFinished = true;
                            break;
                    }
                    Message message = Message.obtain();
                    message.what = UPDATE_DOWNLOAD_PROGRESS;
                    message.arg1 = progress;
                    mainHandler.sendMessage(message);


                }
            }
        }
    });
    executor.shutdown();
    mainHandler.removeCallbacksAndMessages(null);
}
}

I want to show a progress bar to indicate the download's progress but I don't know how to implement it.

I edited my code with suggestions from @Son Truong and have a progress bar in XML

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/gradient"
    tools:context=".Physics">

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="0"
        android:max="100"/>

    <com.github.barteksc.pdfviewer.PDFView
        android:id="@+id/pdfview"
        android:layout_width="match_parent"
        android:layout_height="478dp"
        android:layout_gravity="bottom"
        />

</FrameLayout>

But the progress bar is not starting at the start of download and doesn't finish after the download is done. Also, There is no text to show if how much percentage is completed.


Solution

  • Solution

    Step 1. Declare the following variables in your class

    // Indicate that we would like to update download progress
    private static final int UPDATE_DOWNLOAD_PROGRESS = 1;
    
    // Use a background thread to check the progress of downloading
    private final ExecutorService executor = Executors.newFixedThreadPool(1);
    
    // Use a hander to update progress bar on the main thread
    private final Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if (msg.what == UPDATE_DOWNLOAD_PROGRESS) {
                int downloadProgress = msg.arg1;
    
                // Update your progress bar here.
                progressBar.setProgress(downloadProgress);
            }
            return true;
        }
    });
    

    Step 2. Modify your downloadFile() method

    public void downloadFile(Context context, String fileName, String fileExtension, String destinationDirectory, String url) {
        DownloadManager downloadManager = (DownloadManager) context.
                getSystemService(Context.DOWNLOAD_SERVICE);
    
        Uri uri = Uri.parse(url);
        DownloadManager.Request request = new DownloadManager.Request(uri);
    
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        request.setDestinationInExternalFilesDir(context, destinationDirectory, fileName + fileExtension);
    
        long downloadId = downloadManager.enqueue(request);
    
        // Run a task in a background thread to check download progress
        executor.execute(new Runnable() {
            @Override
            public void run() {
                int progress = 0;
                boolean isDownloadFinished = false;
                while (!isDownloadFinished) {
                    Cursor cursor = downloadManager.query(new DownloadManager.Query().setFilterById(downloadId));
                    if (cursor.moveToFirst()) {
                        int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                        switch (downloadStatus) {
                            case DownloadManager.STATUS_RUNNING:
                                long totalBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                                if (totalBytes > 0) {
                                    long downloadedBytes = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                                    progress = (int) (downloadedBytes * 100 / totalBytes);
                                }
    
                                break;
                            case DownloadManager.STATUS_SUCCESSFUL:
                                progress = 100;
                                isDownloadFinished = true;
                                break;
                            case DownloadManager.STATUS_PAUSED:
                            case DownloadManager.STATUS_PENDING:
                                break;
                            case DownloadManager.STATUS_FAILED:
                                isDownloadFinished = true;
                                break;
                        }
                        Message message = Message.obtain();
                        message.what = UPDATE_DOWNLOAD_PROGRESS;
                        message.arg1 = progress;
                        mainHandler.sendMessage(message);
                    }
                }
            }
        });
    }
    

    Note: Remember to release the executor and handler after downloading.

    executor.shutdown();
    mainHandler.removeCallbacksAndMessages(null);