Android でファイルをダウンロードする

Firebase Storage を使用すると、デベロッパーは Firebase によって提供、管理される Google Cloud Storage バケットから迅速かつ容易にファイルをダウンロードできます。

参照を作成する

ファイルをダウンロードするには、まずダウンロードするファイルへの Firebase Storage 参照を作成します。

参照は、子パスをストレージ ルートに追加して作成するか、または Firebase Storage 内のオブジェクトを参照している既存の gs:// または https:// URL から作成することができます。

 verbatim 04c618c9e232dbbf5d012e25c51e65ff // Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>");

// Create a reference with an initial file path and name
StorageReference pathReference = storageRef.child("images/stars.jpg");

// Create a reference to a file from a Google Cloud Storage URI
StorageReference gsReference = storage.getReferenceFromUrl("gs://bucket/images/stars.jpg");

// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
StorageReference httpsReference = storage.getReferenceFromUrl("https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg"); endverbatim 04c618c9e232dbbf5d012e25c51e65ff 

ファイルをダウンロードする

参照を作成したら、getBytes() または getStream() を呼び出して Firebase Storage からファイルをダウンロードすることができます。別のライブラリのファイルをダウンロードしたい場合は、getDownloadUrl() を使用してダウンロード URL を取得することができます。

メモリにダウンロードする

getBytes() メソッドを使用してファイルを byte[] にダウンロードします。これは最も簡単にファイルをダウンロードできる方法ですが、ファイルのコンテンツ全体をメモリ内に読み込む必要があります。アプリで使用できるメモリよりも大きなファイルをリクエストすると、アプリがクラッシュします。メモリの問題が発生しないように、getBytes() にダウンロードの最大バイト数を設定します。アプリで処理できる範囲内で最大サイズを設定するか、別のダウンロード方法を使用してください。

 verbatim 1212c10b24cb94a46ca616b4e0a200f9 StorageReference islandRef = storageRef.child("images/island.jpg");

final long ONE_MEGABYTE = 1024 * 1024;
islandRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
    @Override
    public void onSuccess(byte[] bytes) {
        // Data for "images/island.jpg" is returns, use this as needed
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
}); endverbatim 1212c10b24cb94a46ca616b4e0a200f9 

ローカル ファイルにダウンロードする

getFile() メソッドはファイルをローカル端末に直接ダウンロードします。ユーザーがオフライン中にファイルにアクセスしたい場合や、別のアプリでファイルを共有したい場合は、このメソッドを使用します。getFile() から返される DownloadTask を使用して、ダウンロードの管理とダウンロード ステータスの監視を行うことができます。

 verbatim e58c199625b71d11a3b9af6eb8ef6282 islandRef = storageRef.child("images/island.jpg");

File localFile = File.createTempFile("images", "jpg");

islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
        // Local temp file has been created
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
}); endverbatim e58c199625b71d11a3b9af6eb8ef6282 

ダウンロードを積極的に管理したい場合は、ダウンロードの管理で詳細をご覧ください。

URL 経由でデータをダウンロードする

URL をベースにしたダウンロード インフラストラクチャが既にある場合や、単に共有するための URL が必要な場合は、ストレージ参照で getDownload() メソッドを呼び出して、ファイルのダウンロード URL を取得することができます。

 verbatim 140bae68440a208694c77169c8712fda storageRef.child("users/me/profile.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
    @Override
    public void onSuccess(Uri uri) {
        // Got the download URL for 'users/me/profile.png'
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
}); endverbatim 140bae68440a208694c77169c8712fda 

FirebaseUI による画像のダウンロード

FirebaseUI にはシンプルでカスタマイズ可能な本番環境対応のモバイル バインドが用意されており、ボイラープレート コードではなく Google お勧めの方法を用いることができるようになります。FirebaseUI では、Glide の統合機能を使用して、Firebase Storage の画像をすばやく簡単にダウンロード、キャッシュ、および表示できます。

まずは FirebaseUI を app/build.gradle に追加します。

dependencies {
    // FirebaseUI Storage only
    compile 'com.firebaseui:firebase-ui-storage:0.6.0'
}

次に、ストレージから ImageView へ直接、画像を読み込みます。

// Reference to an image file in Firebase Storage
StorageReference storageReference = ...;

// ImageView in your Activity
ImageView imageView = ...;

// Load the image using Glide
Glide.with(this /* context */)
        .using(new FirebaseImageLoader())
        .load(storageReference)
        .into(imageView);

アクティビティ ライフサイクルの変更を処理する

アクティビティ ライフサイクル(ダイアログの表示や画面の回転など)が変わった後でも、ダウンロードはバックグラウンドで継続します。指定したリスナーも、指定されたまま残ります。このため、アクティビティが停止した後でリスナーが呼び出されると、予期しない結果になることがあります。

この問題を解決するには、アクティビティの範囲を指定してリスナーを登録します。こうすると、そのアクティビティが停止したときにリスナーは自動的に登録を解除されます。次に、アクティビティが再開したら getActiveDownloadTasks メソッドを使用して、実行中または最近完了したダウンロード タスクを取得します。

以下の例は、上記の手順と、使用するストレージ参照パスを保持する方法を示しています。

StorageReference mStorageRef;  //mStorageRef was previously used to transfer data.

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // If there's a download in progress, save the reference so you can query it later
    if (mStorageRef != null) {
        outState.putString("reference", mStorageRef.toString());
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    // If there was a download in progress, get its reference and create a new StorageReference
    final String stringRef = savedInstanceState.getString("reference");
    if (stringRef == null) {
        return;
    }
    mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef);

    // Find all DownloadTasks under this StorageReference (in this example, there should be one)
    List tasks = mStorageRef.getActiveDownloadTasks();
    if (tasks.size() > 0) {
        // Get the task monitoring the download
        DownloadTask task = tasks.get(0);

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this, new OnSuccessListener() {
          @Override
          public void onSuccess(DownloadTask.TaskSnapshot state) {
             handleSuccess(state); //call a user defined function to handle the event.
          }
        });
    }
}

エラーを処理する

ダウンロード時にエラーが発生する理由として、ファイルが存在しない、目的のファイルのアクセス権がユーザーにないなど、たくさんの理由が考えられます。エラーについて詳しくは、このドキュメントのエラーの処理のセクションをご覧ください。

ダウンロードとエラー処理の完全な例を以下に示します。

 verbatim 76c5d3dfca5bf68e4814d823c8702753 storageRef.child("users/me/profile.png").getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
    @Override
    public void onSuccess(byte[] bytes) {
        // Use the bytes to display the image
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
}); endverbatim 76c5d3dfca5bf68e4814d823c8702753 

Firebase Storage に保存されているファイルのメタデータを取得、更新することもできます。

フィードバックを送信...