我使用Android Drive Api将文件上传到云端硬盘上。我在Google云端硬盘根目录上创建了一个文件夹(" NewFolder")并在我的内部创建了一个内部文件夹(" InnerFolder") " NewFolder"从Android应用程序使用以下代码。然后我在这个" InnerFolder"上写我的文件。来自我的Android应用程序。
我的应用创建了" InnerFolder"首次安装在我的设备上。然后卸载并重新安装App将不再创建文件夹(在本地文件中存储创建的文件夹Drive Id(如DriveId:yrjundeen12cnfe))。
我的代码在第一次安装时工作正常。但是如果我多次卸载并重新安装应用程序并尝试在Google云端硬盘上传,则会出现错误,因为"无效的父文件夹"关于createFile的回调方法。
首次创建文件夹代码:
private void createGalleryFolder() {
DriveFolder folder = Drive.DriveApi.getRootFolder(googleApiClient);
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(AppConstants.DEFAULT_GALLERY_NAME).build();
folder.createFolder(googleApiClient, changeSet).setResultCallback(
createRootFolderCallback);
}
final ResultCallback<DriveFolderResult> createRootFolderCallback = new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
showError();
return;
}
// Root folder created Successfully
DriveId mFolderDriveId = result.getDriveFolder().getDriveId();
AppUtilities.saveOnLocalFile(mFolderDriveId, AppConstants.ROOT_FOLDER_ID_FILE);
if (!deviceID.equalsIgnoreCase("")) {
DriveFolder folder = Drive.DriveApi.getFolder(googleApiClient,
result.getDriveFolder().getDriveId());
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(deviceID).build();
folder.createFolder(googleApiClient, changeSet)
.setResultCallback(createInnerFolderCallback);
} else {
showError(); }
}
};
final ResultCallback<DriveFolderResult> createInnerFolderCallback = new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
showError();
return;
}
// IMEI folder created successfully inside the Root folder
DriveId mFolderDriveId = result.getDriveFolder().getDriveId();
AppUtilities.saveOnLocalFile(mFolderDriveId, AppConstants.INNER_FOLDER_ID_FILE);
// Success
}
};
文件上传代码:
private void saveFileToDrive(final Bitmap bitmapToSave,final File imageFile,final String imageName) {
Drive.DriveApi.newDriveContents(googleApiClient).setResultCallback(driveContentsCallback);
}
final private ResultCallback<DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveContentsResult>() {
@Override
public void onResult(DriveContentsResult result) {
if(!result.getStatus().isSuccess()){
Log.i("Test1", "Failed to create new contents");
return;
}
Log.i("Test1", "New contents created");
//Write image data to OutputStream
OutputStream outputStream = result.getDriveContents().getOutputStream();
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
bitmapToSave.compress(Bitmap.CompressFormat.JPEG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
DriveFolder folder = Drive.DriveApi.getFolder(googleApiClient, DriveId.decodeFromString(getFolderDriveID()));
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(imageName)
.setMimeType("image/jpeg")
.setStarred(false).build();
folder.createFile(googleApiClient, changeSet, result.getDriveContents()).setResultCallback(fileCallback);
} catch (IOException e) {
Log.i("Test1","Unable to write file contents");
}
}
};
final private ResultCallback<DriveFileResult> fileCallback =
new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
Log.i("Test1","Error while trying to create the file "+result.getStatus().getStatusMessage());
return;
}
Log.i("Test1","Created a file: " + result.getDriveFile().getDriveId());
result.getDriveFile().getMetadata(googleApiClient).setResultCallback(fileUploadedResultCallback);
}
};
final private ResultCallback<MetadataResult> fileUploadedResultCallback =
new ResultCallback<MetadataResult>() {
@Override
public void onResult(MetadataResult result) {
if(!result.getStatus().isSuccess()){
Log.i("Test1", "Failed to upload");
return;
}
Log.i("Test1", "File uploaded");
}
};
ResultCallback错误:
D/dalvikvm( 584): threadid=50: interp stack at 0x549a5000
D/dalvikvm( 584): threadid=50: calling run()
I/Test1 ( 813): Image added
--------- beginning of /dev/log/system
D/ActivityThread( 584): SVC-CREATE_SERVICE handled : 0 / CreateServiceData{token=android.os.BinderProxy@415dbf40 className=com.google.android.gms.drive.api.DriveAsyncService packageName=com.google.android.gms intent=null}
D/ActivityThread( 584): SVC-Calling onStartCommand: com.google.android.gms.drive.api.DriveAsyncService@415b6480, flags=2, startId=1
D/ActivityThread( 584): SVC-SERVICE_ARGS handled : 0 / ServiceArgsData{token=android.os.BinderProxy@415dbf40 startId=1 args=Intent { act=com.google.android.gms.drive.EXECUTE pkg=com.google.android.gms }}
W/DataServiceConnectionImpl( 584): Could not find entry, and no valid resource id: DriveId:CAESABgGIMq7nNDgUg==
E/DriveAsyncService( 584): Invalid parent folder.
E/DriveAsyncService( 584): OperationException[Status{statusCode=Invalid parent folder., resolution=null}]
E/DriveAsyncService( 584): at com.google.android.gms.drive.api.e.e(SourceFile:619)
E/DriveAsyncService( 584): at com.google.android.gms.drive.api.e.a(SourceFile:458)
E/DriveAsyncService( 584): at com.google.android.gms.drive.api.a.n.a(SourceFile:82)
E/DriveAsyncService( 584): at com.google.android.gms.drive.api.a.b.a(SourceFile:27)
E/DriveAsyncService( 584): at com.google.android.gms.common.service.c.onHandleIntent(SourceFile:60)
E/DriveAsyncService( 584): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
E/DriveAsyncService( 584): at android.os.Handler.dispatchMessage(Handler.java:99)
E/DriveAsyncService( 584): at android.os.Looper.loop(Looper.java:154)
E/DriveAsyncService( 584): at android.os.HandlerThread.run(HandlerThread.java:65)
I/Test1 ( 813): Error while trying to create the file Invalid parent folder.
答案 0 :(得分:3)
不要依赖GDAA's DriveId 进行应用和设备范围之外的任何缓存或可能的Drive对象(文件/文件夹)寻址。此ID来自您设备上的Google Play服务实例(因此即使文件/文件夹在FILE范围内仍然可见,它甚至在使用同一应用的其他设备上也无效)。即使在清除Google Play服务(GooPS)缓存甚至重新安装GooPS时,我依旧记得“丢失”它。但这可能已经修复了。几个月前我与GDAA的最后一次见面。
相反,RESTFul API中使用了'ResourceId'(称为普通'id') - 请参阅SO 21800257。此字符串唯一地表示Drive对象,可以在任何地方移植和使用(它甚至是Drive Web界面中HTTP地址的一部分)。
不幸的是,ResourceId不是立即可用的(直到GDAA提交该对象) - SO 22432431
祝你好运
答案 1 :(得分:1)
您无法访问在其他应用(包括云端硬盘和Android应用)中创建的文件和文件夹,除非用户明确授权您的应用使用文件选择器访问它们。
如果您使用Android应用创建了该文件夹,然后卸载并重新安装您的应用,则您的应用仍然可以访问该文件夹,因为授权与您的开发者控制台应用ID无关,而且不会在安装之间进行更改。
此行为还表示您的应用的Web版本可以访问由Android版本创建的文件。