DownloadManagerを使ってファイルをダウンロードする


先日、GoogleからAndroid SDK 2.3が発表されました。Android Developers内の紹介ページはこちらです。

SDKの概要は色々なサイトで紹介されているので、TechBoosterでは2.3(API Level9)から追加された新機能をどのように使うのかというところに着目して紹介していきたいと思います。

今回は、ダウンロードマネージャ(DownloadManager)について紹介します。

ダウンロードマネージャ(DownloadManager)は、サイズの大きいファイルをダウンロードするときに用いるクラスです。ダウンロードの状態を通知領域に表示させることも可能です。

DownloadManagerに関連するクラスが他に2つあり、今回は下記の3つのクラスを使ったサンプルを用意してみました。

  • DownloadManager
  • DownloadManager.Query
  • DownloadManager.Request

それでは続きでサンプルコードと共に説明してきます。

大まかな手順

  1. DownloadManagerのインスタンスを取得する
  2. URIを引数にしてDownloadManager.Requestクラスのインスタンスを生成する
  3. ダウンロードしたファイルの保存先や必要に応じてその他の設定をインスタンスに行う
  4. DownloadManagerに対してenqueueメソッドでキューに追加する
  5. 必要であればダウンロード完了のブロードキャストを受けて処理を行う

キューに追加することで順次ダウンロードが開始されます。

DownloadManagerのインスタンスを取得する

それでは実際にDownloadManagerを使ってみようと思います。

まずはDownloadManagerのインスタンスを取得します。

DOWNLOAD_SERVICEを引数に与えてgetSystemServiceメソッドを呼び出すことで取得することができます。

downLoadManager_ = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);

DownloadManager.Requestクラス

RequestクラスのコンストラクタはURIクラスを引数にするのでまずはダウンロードするファイルのURIクラスを生成します。

Uri.Builder uriBuilder = new Uri.Builder();
uriBuilder.scheme("http");
uriBuilder.authority("www.cross-bridge.jp");
uriBuilder.path("/TechBooster.pdf");

準備したURIクラスを引数にしてRequestクラスのインスタンスを生成します。

Request request = new Request(uriBuilder.build());
request.setDestinationInExternalFilesDir(getApplicationContext(), Environment.DIRECTORY_DOWNLOADS, "/temp.pdf");
request.setTitle("TechBooster");
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
request.setMimeType("application/pdf");

setDestinationInExternalFilesDirメソッドでダウンロードするファイルの保存先をします。
他にも下記のメソッドで保存先を指定できるようです。

  • setDestinationUri (Uri uri)
  • setDestinationInExternalPublicDir (String dirType, String subPath)


setAllowedNetworkTypesメソッドはダウンロードするときに許可する通信方法を指定します。

デフォルトではモバイル通信(3Gなど)/WiFiともに許可していますが、ファイルサイズが大きい場合などはWiFiだけ許可するという使い方もできます。

サンプルではフラグの指定の方法を示すために両方とも許可しているため、デフォルトと同じ動作をすることになります。

setTitleメソッドでは通知領域に表示される名前を設定します。設定しなければ保存するファイル名が表示されます。

Requestをキューに追加してダウンロードを開始する

DownLoadManagerクラスのenqueueメソッドでキューに追加します。戻り値としてlong型でIDが返ってきます。ダウンロードが完了した時にステータスを確認したり、ダウンロードをキャンセルする場合にこのIDを指定することになります。

id_ = downLoadManager_.enqueue(request);

完了通知を受け取る

DownloadManagerが投げるブロードキャストは下記の3つがあります。

  • android.intent.action.DOWNLOAD_COMPLETE
  • android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED
  • android.intent.action.VIEW_DOWNLOADS

ダウンロードの完了(失敗時を含む)や、通知領域がタッチ(クリック)されたことなどを検知することができます。

他のブロードキャストIntentと同様にBroadcastReceiverを継承したクラスを作成してonReceiveメソッドをオーバーライドして処理を書くことになります。マニフェストファイルへのIntent-Filterの設定を忘れずに行いましょう。

ステータスを確認する

キューに追加したリクエストのステータスなどを確認するにはまず、DownloadManagerクラスのqueryメソッドを使います。
queryメソッドの戻り値でCursorクラスを得られるのですが、引数に指定するDownloadManager.Queryクラスによってフィルタリングします。

DownloadManager.QueryクラスにはIDでsetFilterByIdメソッドと、ステータスでフィルタリングするsetFilterByStatusメソッドがあります。

完了したリクエストの一覧を得たい場合や、失敗したリクエストの一覧を得たい場合にはsetFilterByStatusメソッドを使うことになります。 今回はサンプルとして、開始したリクエストのIDを覚えておいてそのIDのステータスを確認する処理を示します。 DownloadManager.COLUMN_STATUSで得られるステータスの詳細はこちらのドキュメントを参照してください。

Query query = new Query();
query.setFilterById(id_);
Cursor cursor = downLoadManager_.query(query);
int idStatus = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
cursor.moveToFirst();
Log.d("DownloadManagerSample", cursor.getString(idStatus));

リクエストをキャンセルする

最後にリクエストをキャンセルする方法を紹介しておきます。

キャンセルするにはDownloadManageクラスのremoveメソッドを使います。

enqueueメソッドの戻り値で得られたIDを引数に与えることでキャンセルすることができます。

downLoadManager_.remove(キャンセルしたいリクエストのID);

最後に

DownloadManagerに関するドキュメントはこちらになります。

http://developer.android.com/reference/android/app/DownloadManager.html

http://developer.android.com/reference/android/app/DownloadManager.Request.html

http://developer.android.com/reference/android/app/DownloadManager.Query.html