GoogleドライブAPIを使用してGoogleドライブのアプリフォルダにファイルを保存していますが、ファイルをダウンロードしようとすると一部のデバイスでは単に0バイトのサイズのファイルが返されます。Android用GoogleドライブAPIは空のファイルを返します
アップロードコード:
/**
* 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以下です。
Googleドライブアピ9.2.1
Googleは9.4.52日付サービスを再生する:2016年7月19日最新版