Android Basic Training Course: DownloadManager Example

    The DownloadManager was introduced in Android 2.3 (API level 9). It’s a System Service that optimizes the handling of long-running downloads in the background. The download manager handles HTTP connections, monitors connectivity changes, reboots, and ensures each download completes successfully It's good practice to use the download manager for most downloads, especially if the download continues between user sessions or if success is important.

    In this example, I’m going to use the built-in DownloadManager to download an image file and handle it's completion via a BroadcastReceiver.
    Define a layout file (XML) for our main activity first:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Start Download" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/activity_horizontal_margin"
        android:contentDescription="@null"
        android:src="@mipmap/ic_launcher" />
</LinearLayout>
In activity programmatically code, access the DownloadManager, request the DOWNLOAD_SERVICE using the getSystemService():
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE)
Create a download request through initializing a Request object with a URL string:
Request request = new Request(Uri.parse(DOWNLOAD_URL));
After that, your you have to put it into the queue by this code:
enqueue = downloadManager.enqueue(request);
Now, the DownloadManager will carry out download work!
In the main activity, I create a BroadcastReceiver to handling it's completion. Full source code for this activity:
MainActivity.java
package info.devexchanges.downloadingfile;

import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
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.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.webkit.URLUtil;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private long enqueue;
    private DownloadManager downloadManager;
    private final static String DOWNLOAD_URL = "http://i.imgur.com/wsibrEw.gif";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                    intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                    Query query = new Query();
                    query.setFilterById(enqueue);
                    Cursor cursor = downloadManager.query(query);
                    if (cursor.moveToFirst()) {
                        int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
                        if (DownloadManager.STATUS_SUCCESSFUL == cursor.getInt(columnIndex)) {
                            ImageView view = (ImageView) findViewById(R.id.imageView);
                            String uriString = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                            view.setImageURI(Uri.parse(uriString));
                            Toast.makeText(MainActivity.this, "Download completed!", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }
        };

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

    public void onClick(View view) {
        downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        Request request = new Request(Uri.parse(DOWNLOAD_URL));

        //Get download file name
        String fileExtenstion = MimeTypeMap.getFileExtensionFromUrl(DOWNLOAD_URL);
        String name = URLUtil.guessFileName(DOWNLOAD_URL, null, fileExtenstion);

        //Save file to destination folder
        request.setDestinationInExternalPublicDir("/Downloads", name);

        enqueue = downloadManager.enqueue(request);
    }
}
Never forget to add Internet and write file permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Running application, we'll have this output:
    Click "Start Download", the downloading process will be invoked. This is it's notification:
    When the image downloaded, it will be set to the ImageView:
    If you open "Downloads" application in your device, you will see this completed work:
    Open "File Manager" application, you will see the downloaded file in "Downloads" folder:

Conclusions

    I have presented some basic features of DownloadManager in Android SDK through downloading a file from Internet and saving it to SD card. For more details, please read it's official document to find out some custom features when initiate a download (adding title, description, allow only wifi,...). Finally, you can take my project from @Github.



Update: Runtime permission from Android M

    From version 6.0, Android divide permissions into 2 categories: normal and dangerous permissions. Downloading file need WRITE_EXTERNAL_STORAGE permission so you must request it at the runtime. Please read my NEWER POST to understanding this new mechanism.

Share


Previous post
« Prev Post
Next post
Next Post »