在 Android 上下载文件

Cloud Storage 允许开发者从 Firebase 提供和管理的 Google Cloud Storage 存储分区快速轻松地下载文件。

创建引用

要下载文件,请首先为要下载的文件创建一个 Cloud Storage 引用

您可以通过将子路径附加到存储根目录来创建引用,也可以从指向 Cloud Storage 中的对象的现有 gs://https:// 网址创建引用。

// Create a storage reference from our app
StorageReference storageRef = storage.getReference();

// 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");

下载文件

有了引用之后,您可以通过调用 getBytes()getStream() 从 Cloud Storage 下载文件。如果您希望使用其他库下载文件,则可以使用 getDownloadUrl() 获取下载地址。

下载至内存

使用 getBytes() 方法将文件下载至 byte[]。这是最简单的文件下载方法,但它必须将文件的全部内容加载到内存中。如果您请求下载的文件大于应用的可用内存,则您的应用将崩溃。为防止内存出现问题,getBytes() 设置了下载的最大字节数限制。将大小上限设为应用可以处理的大小,或者使用其他下载方法。

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
    }
});

下载至本地文件

getFile() 方法可将文件直接下载至本地设备。如果用户希望离线时可以访问文件或希望在不同的应用中分享文件,请使用这种方法。getFile() 会返回一个 DownloadTask,您可以使用它管理下载和监视下载的状态。

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
    }
});

如果您希望主动管理下载,请参阅管理下载以了解详情。

通过网址下载数据

如果您已经有了基于网址的下载基础架构,或者只想要一个网址以便共享,则可通过调用存储引用中的 getDownloadUrl() 方法来获取文件的下载网址。

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
    }
});

通过 FirebaseUI 下载图片

FirebaseUI 提供简单、定制化并且随时可以部署的原生移动绑定以消除样板代码并促进实施 Google 最佳做法。使用 FirebaseUI,您可以快速轻松地下载、缓存和显示 Cloud Storage 中的图片,与 Glide 相整合。

首先,将 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);

处理 Activity 生命周期变更

即使 Activity 生命周期 发生变化(例如显示对话框或旋转屏幕),下载也将继续在后台进行。您连接的任何侦听器也都会保持连接状态。如果在 Activity 停止后调用这些侦听器,会产生意外结果。

向 Activity 作用域订阅您的侦听器,以便在 Activity 停止时自动注销它们,通过这种方式可以解决此问题。然后,在 Activity 重新启动后使用 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<FileDownloadTask> tasks = mStorageRef.getActiveDownloadTasks();
    if (tasks.size() > 0) {
        // Get the task monitoring the download
        FileDownloadTask task = tasks.get(0);

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

处理错误

导致下载出错的原因有很多,包括文件不存在或用户无权访问所需文件。如需了解有关错误的详细信息,请参阅文档的处理错误部分。

完整示例

包含错误处理的下载完整示例如下:

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
    }
});

对于存储在 Cloud Storage 中的文件,您还可以获取和更新元数据

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面