【问题标题】:Google Drive API for Android returns empty file适用于 Android 的 Google Drive API 返回空文件
【发布时间】:2016-08-20 08:59:41
【问题描述】:

我正在使用 google drive api 将一些文件存储在 google drive app 文件夹中,但是在某些设备上,当我尝试下载文件时,它只会返回大小为 0 字节的文件。

上传代码:

/**
 * It's a blocking method
 *
 * @param file the file to upload to google drive.
 */
private boolean uploadToDrive(@NonNull File file) {
    final DriveApi.DriveContentsResult driveContentsResult = Drive.DriveApi
            .newDriveContents(mGoogleApiClient)
            .await();
    // If the operation was not successful, we cannot do anything and must fail.
    if (!driveContentsResult.getStatus().isSuccess()) {
        Logger.t(TAG).e("Failed to create new contents.");
        return false;
    }
    // Otherwise, we can write our data to the new contents.
    Logger.t(TAG).i("New empty contents created.");

    //Creates a file in app folder with provided metadata.
    final DriveFolder.DriveFileResult driveFileResult = Drive.DriveApi
            .getAppFolder(mGoogleApiClient)
            .createFile(mGoogleApiClient, getDatabaseMeta(file.getName().replace("temp-", "")), driveContentsResult.getDriveContents())
            .await();

    if (!driveContentsResult.getStatus().isSuccess()) {
        Logger.t(TAG).e("Error while trying to create the file in app folder.");
        return false;
    }

    final DriveApi.DriveContentsResult contentsResult = driveFileResult
            .getDriveFile()
            .open(mGoogleApiClient, DriveFile.MODE_WRITE_ONLY, null)
            .await();

    if (!contentsResult.getStatus().isSuccess()) {
        Logger.t(TAG).e("cant create a file in app folder");
        return false;
    }

    final DriveContents driveContents = contentsResult.getDriveContents();

    if (!writeFileToDrive(file, driveContents)) {
        Logger.t(TAG).e("Cannot read or write to file");
        return false;
    }

    final Status status = driveContents.commit(mGoogleApiClient, null).await();

    if (!status.getStatus().isSuccess()) {
        Logger.t(TAG).e("Cannot upload the file to drive");
        return false;
    }
    // TODO: 2016-01-19 Store this to use this this file later.
    Logger.t(TAG).e("getDriveId:" + driveFileResult.getDriveFile().getDriveId().encodeToString());
    return true;
}
/**
 * Write the source file to destination drive contents file.
 *
 * @param file          the source {@link File} to read from.
 * @param driveContents the destination {@link DriveContents} to write to.
 */
private boolean writeFileToDrive(File file, DriveContents driveContents) {
    try {
        FileInputStream is = new FileInputStream(file);
        BufferedInputStream in = new BufferedInputStream(is);
        byte[] buffer = new byte[8 * 1024];

        BufferedOutputStream out = new BufferedOutputStream(driveContents.getOutputStream());
        int n;
        while ((n = in.read(buffer)) > 0) {
            out.write(buffer, 0, n);
        }
        in.close();
        is.close();
        out.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

下载代码:

@Nullable
private DriveContents downloadFileFromDrive(@NonNull DriveId driveId) {

    final DriveApi.DriveContentsResult driveContentsResult = driveId.asDriveFile().open(mGoogleApiClient, DriveFile.MODE_READ_ONLY, new DriveFile.DownloadProgressListener() {
        @Override
        public void onProgress(long bytesDownloaded, long bytesExpected) {
            Log.d(TAG, "onProgress() called with: bytesDownloaded = [" + bytesDownloaded + "], bytesExpected = [" + bytesExpected + "]");
        }
    }).await();
    if (!driveContentsResult.getStatus().isSuccess()) {
        Logger.t(TAG).e("Cannot download the file");
        return null;
    }
    return driveContentsResult.getDriveContents();
}

/**
 * Writes the drive contents to the destination file.
 *
 * @param source
 * @param destination
 * @return true if the write is successful.
 */
private boolean writeFileToDisk(@NonNull DriveContents source, @NonNull File destination) {
    try {
        final InputStream in = source.getInputStream();
        final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(destination));
        byte[] buffer = new byte[8 * 1024];

        int n;
        while ((n = in.read(buffer)) > 0) {
            out.write(buffer, 0, n);
        }
        out.close();
        in.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

上传的文件在模拟器和大多数设备上都能正确下载,但在某些设备上下载的文件大小为 0 字节。

实际上,当我从有此问题的设备上传文件,然后我请求再次使用同一设备下载它时,如果我尝试从另一个设备下载该文件,我会从缓存中收到一个长度为零的文件这个问题直接下载没问题。

我认为它的缓存策略有问题,它只是检查文件是否已经存在于缓存中并以0字节大小返回。

我遇到此问题的设备是 api 21 及以下版本。

谷歌云端硬盘 API 9.2.1

Google Play Services 9.4.52 日期:2016 年 7 月 19 日最新版本

【问题讨论】:

    标签: android google-play-services google-drive-android-api drive


    【解决方案1】:

    我有同样的错误。我发现,我要下载的 DriveId 是“初步”DriveId(关注此resourceID of file is null)。我将“初步”DriveId 保存到我的数据库中,但无法下载该文件。 我通过在创建和编辑文件时接收 CompletionEvents 来解决此问题,以便在 GDAA 将文件提交到 Drive 时获取文件的真实资源 ID(receiving Completion Events)。对不起我的英语不好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 2014-11-01
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多