Android Drive API无效的父文件夹错误

时间:2014-12-21 18:38:42

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

我使用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.

2 个答案:

答案 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版本创建的文件。