ZOFTINO.COM android and web dev tutorials

Long Running HTTP Downloads in Android

If your app needs to download large files which take time, the best option to perform long running downloads is to use android system provided DownloadManager. DownloadManager service handles http downloads. Download can be requested by specifying uri and target location. DownloadManager has the capability to retry failed downloads. It does so even in the case of system reboots, so it ensures that requested file is always downloaded.

Steps to Download Large Files Using DownloadManager

  • Get the DownloadManager service by calling getSystemService().
  • Create a Request object passing URI.
  • Send request to download manager by calling enqueue() method on download manager, this method returns unique download id for each request, which can be used for future calls to download manager to perform other operations.
  • Create a broadcast receiver and register the receiver passing type of broad cast intent interested in. Download manager sends broad cast intent actions such as ACTION_DOWNLOAD_COMPLETE, ACTION_NOTIFICATION_CLICKED and ACTION_VIEW_DOWNLOADS.

Activity

package com.zoftino.content;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;


public class DownloadManagerActivity extends AppCompatActivity {
    private long reqid;
    private TextView tv;
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dm);

        tv = (TextView)findViewById(R.id.download_status);

        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                    long downloadId = intent.getLongExtra(
                            DownloadManager.EXTRA_DOWNLOAD_ID, 0);

                    DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                    DownloadManager.Query query = new DownloadManager.Query();
                    query.setFilterById(downloadId);
                    Cursor c = downloadManager.query(query);
                    if (c.moveToFirst()) {
                      String fileTitle =   c.getString(c.getColumnIndex(DownloadManager.COLUMN_TITLE));
                      String localPath =   c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                      Snackbar snackbar = Snackbar.make(findViewById(R.id.activity_dm), "DOWNLOAD COMPLETE "+fileTitle
                                    + " "+localPath, Snackbar.LENGTH_LONG);
                      snackbar.show();
                    }

                }
            }
        };

        registerReceiver(receiver, new IntentFilter(
                DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    public void downloadFile(View view) {
        DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(
                Uri.parse("http://www.zoftino.com/how-to-create-browse-files-option-in-android"));
        reqid = downloadManager.enqueue(request);

    }
    public void viewDownloads(View view) {
        Intent i = new Intent();
        i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
        startActivity(i);
    }
    public void getDownloadStatus(View view) {
        DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(reqid);
        Cursor c = downloadManager.query(query);
        if (c.moveToFirst()) {

            switch (c.getInt(c
                    .getColumnIndex(DownloadManager.COLUMN_STATUS))){
                case DownloadManager.STATUS_SUCCESSFUL:
                    tv.setText("Download successful");
                    break;
                case DownloadManager.STATUS_FAILED:
                    tv.setText("Download failed");
                    break;
                case DownloadManager.STATUS_PAUSED:
                    tv.setText("Download paused");
                    break;
                case DownloadManager.STATUS_PENDING:
                    tv.setText("Download pending");
                    break;
                case DownloadManager.STATUS_RUNNING:
                    long downloadedbytes = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                    tv.setText("Downing in progress "+downloadedbytes);
                    break;
            }

        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(receiver);
    }
}

Activity layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_dm"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.zoftino.content.DownloadManagerActivity">
    <TextView
        android:id="@+id/download_status"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"></TextView>

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="downloadFile"
        android:text="Download File"></Button>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="viewDownloads"
        android:text="View Downloads"></Button>

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="getDownloadStatus"
        android:text="Download Status"></Button>

</LinearLayout>