强制 Android 的驱动器 API 仅在在线模式下工作
Enforce Drive API for Android to work online mode only
最近,我刚刚设法从 Google APIs Client Library Java 迁移了与 Drive API 相关的代码至 Google 播放服务客户端库
以下代码是在 appdata 文件夹中搜索一个文件,然后将其下载为临时文件。
private static GoogleCloudFile searchFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
DriveFolder driveFolder = Drive.DriveApi.getAppFolder(googleApiClient);
final String titleName = ("my-title");
Query query = new Query.Builder()
.addFilter(Filters.and(
Filters.contains(SearchableField.TITLE, titleName),
Filters.eq(SearchableField.TRASHED, false)
))
.build();
DriveApi.MetadataBufferResult metadataBufferResult = driveFolder.queryChildren(googleApiClient, query).await();
if (metadataBufferResult == null) {
return null;
}
Status status = metadataBufferResult.getStatus();
if (!status.isSuccess()) {
h.handleStatus(status);
return null;
}
MetadataBuffer metadataBuffer = null;
boolean needToReleaseMetadataBuffer = true;
try {
metadataBuffer = metadataBufferResult.getMetadataBuffer();
if (metadataBuffer != null ) {
long checksum = 0;
long date = 0;
int version = 0;
Metadata metadata = null;
for (Metadata md : metadataBuffer) {
if (p.isCancelled()) {
return null;
}
if (md == null || !md.isDataValid()) {
continue;
}
final String title = md.getTitle();
// ...
metadata = md;
break;
} // for
if (metadata != null) {
// Caller will be responsible to release the resource. If release too early,
// metadata will not readable.
needToReleaseMetadataBuffer = false;
return GoogleCloudFile.newInstance(metadataBuffer, metadata, checksum, date, version);
}
} // if
} finally {
if (needToReleaseMetadataBuffer) {
if (metadataBuffer != null) {
metadataBuffer.release();
}
}
}
return null;
}
public static CloudFile loadFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
final java.io.File directory = ...
GoogleCloudFile googleCloudFile = searchFromGoogleDrive(googleApiClient, h, p);
if (googleCloudFile == null) {
return null;
}
try {
DriveFile driveFile = googleCloudFile.metadata.getDriveId().asDriveFile();
DriveApi.DriveContentsResult driveContentsResult = driveFile.open(googleApiClient, DriveFile.MODE_READ_ONLY, null).await();
if (driveContentsResult == null) {
return null;
}
Status status = driveContentsResult.getStatus();
if (!status.isSuccess()) {
h.handleStatus(status);
return null;
}
final long checksum = googleCloudFile.checksum;
final long date = googleCloudFile.date;
final int version = googleCloudFile.version;
p.publishProgress(MyApplication.instance().getString(R.string.downloading));
final DriveContents driveContents = driveContentsResult.getDriveContents();
InputStream inputStream = null;
java.io.File outputFile = null;
OutputStream outputStream = null;
try {
inputStream = driveContents.getInputStream();
outputFile = java.io.File.createTempFile("me", ".zip", directory);
outputFile.deleteOnExit();
outputStream = new FileOutputStream(outputFile);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (IOException ex) {
Log.e(TAG, "", ex);
} finally {
org.yccheok.file.Utils.close(outputStream);
org.yccheok.file.Utils.close(inputStream);
driveContents.discard(googleApiClient);
}
if (outputFile == null) {
return null;
}
return CloudFile.newInstance(outputFile, checksum, date, version);
} finally {
googleCloudFile.metadataBuffer.release();
}
}
以前,当我为 Java 使用 Google APIs 客户端库时,类似的代码只会抛出异常,如果没有互联网连接。
但是,当我使用 Google Play 服务客户端库 时,上面的代码仍然可以成功运行,即使我有我的设备飞行模式,关闭wifi。
Google Play 服务客户端库 中的驱动器 API 似乎能够在没有互联网连接时读取离线文件。
有没有办法,在没有互联网连接的情况下,执行上述代码会失败?因为,我想避免让我的用户下载过时的云文件的风险。
无法按您的要求强制失败。
您可以做的是在查询之前请求与服务器同步:https://developers.google.com/android/reference/com/google/android/gms/drive/DriveApi.html#requestSync(com.google.android.gms.common.api.GoogleApiClient)
如果没有连接,同步将因网络错误而失败。
最近,我刚刚设法从 Google APIs Client Library Java 迁移了与 Drive API 相关的代码至 Google 播放服务客户端库
以下代码是在 appdata 文件夹中搜索一个文件,然后将其下载为临时文件。
private static GoogleCloudFile searchFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
DriveFolder driveFolder = Drive.DriveApi.getAppFolder(googleApiClient);
final String titleName = ("my-title");
Query query = new Query.Builder()
.addFilter(Filters.and(
Filters.contains(SearchableField.TITLE, titleName),
Filters.eq(SearchableField.TRASHED, false)
))
.build();
DriveApi.MetadataBufferResult metadataBufferResult = driveFolder.queryChildren(googleApiClient, query).await();
if (metadataBufferResult == null) {
return null;
}
Status status = metadataBufferResult.getStatus();
if (!status.isSuccess()) {
h.handleStatus(status);
return null;
}
MetadataBuffer metadataBuffer = null;
boolean needToReleaseMetadataBuffer = true;
try {
metadataBuffer = metadataBufferResult.getMetadataBuffer();
if (metadataBuffer != null ) {
long checksum = 0;
long date = 0;
int version = 0;
Metadata metadata = null;
for (Metadata md : metadataBuffer) {
if (p.isCancelled()) {
return null;
}
if (md == null || !md.isDataValid()) {
continue;
}
final String title = md.getTitle();
// ...
metadata = md;
break;
} // for
if (metadata != null) {
// Caller will be responsible to release the resource. If release too early,
// metadata will not readable.
needToReleaseMetadataBuffer = false;
return GoogleCloudFile.newInstance(metadataBuffer, metadata, checksum, date, version);
}
} // if
} finally {
if (needToReleaseMetadataBuffer) {
if (metadataBuffer != null) {
metadataBuffer.release();
}
}
}
return null;
}
public static CloudFile loadFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
final java.io.File directory = ...
GoogleCloudFile googleCloudFile = searchFromGoogleDrive(googleApiClient, h, p);
if (googleCloudFile == null) {
return null;
}
try {
DriveFile driveFile = googleCloudFile.metadata.getDriveId().asDriveFile();
DriveApi.DriveContentsResult driveContentsResult = driveFile.open(googleApiClient, DriveFile.MODE_READ_ONLY, null).await();
if (driveContentsResult == null) {
return null;
}
Status status = driveContentsResult.getStatus();
if (!status.isSuccess()) {
h.handleStatus(status);
return null;
}
final long checksum = googleCloudFile.checksum;
final long date = googleCloudFile.date;
final int version = googleCloudFile.version;
p.publishProgress(MyApplication.instance().getString(R.string.downloading));
final DriveContents driveContents = driveContentsResult.getDriveContents();
InputStream inputStream = null;
java.io.File outputFile = null;
OutputStream outputStream = null;
try {
inputStream = driveContents.getInputStream();
outputFile = java.io.File.createTempFile("me", ".zip", directory);
outputFile.deleteOnExit();
outputStream = new FileOutputStream(outputFile);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (IOException ex) {
Log.e(TAG, "", ex);
} finally {
org.yccheok.file.Utils.close(outputStream);
org.yccheok.file.Utils.close(inputStream);
driveContents.discard(googleApiClient);
}
if (outputFile == null) {
return null;
}
return CloudFile.newInstance(outputFile, checksum, date, version);
} finally {
googleCloudFile.metadataBuffer.release();
}
}
以前,当我为 Java 使用 Google APIs 客户端库时,类似的代码只会抛出异常,如果没有互联网连接。
但是,当我使用 Google Play 服务客户端库 时,上面的代码仍然可以成功运行,即使我有我的设备飞行模式,关闭wifi。
Google Play 服务客户端库 中的驱动器 API 似乎能够在没有互联网连接时读取离线文件。
有没有办法,在没有互联网连接的情况下,执行上述代码会失败?因为,我想避免让我的用户下载过时的云文件的风险。
无法按您的要求强制失败。
您可以做的是在查询之前请求与服务器同步:https://developers.google.com/android/reference/com/google/android/gms/drive/DriveApi.html#requestSync(com.google.android.gms.common.api.GoogleApiClient)
如果没有连接,同步将因网络错误而失败。