Google Drive Android API:已删除的文件夹仍存在于查询中

时间:2015-09-11 19:29:27

标签: android google-drive-android-api

运行下面的代码,我在平板电脑上创建了一个包含Google Drive Android API的文件夹。几秒钟后,从PC上的远程位置删除该文件夹。当我重新运行代码时,API仍然认为“MyFolder”存在,即使它已被删除且在平板电脑上的Google云端硬盘应用中不可见。文件夹持久性最终会在一段时间后消失,代码按预期工作。这是云驱动器的预期行为吗?

Query query = new Query.Builder()
        .addFilter(Filters.and(Filters.eq(
                SearchableField.TITLE, "MyFolder"),
                Filters.eq(SearchableField.TRASHED, false)))
        .build();
Drive.DriveApi.query(getGoogleApiClient(), query)
        .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
    @Override
    public void onResult(DriveApi.MetadataBufferResult result) {
        if (!result.getStatus().isSuccess()) {
            showMessage("Cannot create folder in the root.");
        } else {
            boolean isFound = false;
            for(Metadata m : result.getMetadataBuffer()) {
                if(!isFound) {
                    if (m.getTitle().equals("MyFolder")) {
                        showMessage("Folder exists");
                        isFound = true;
                    }
                }
            }
            if(!isFound) {
                showMessage("Folder not found; creating it.");
                MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                        .setTitle("MyFolder")
                        .build();
                Drive.DriveApi.getRootFolder(getGoogleApiClient())
                        .createFolder(getGoogleApiClient(), changeSet)
                        .setResultCallback(new ResultCallback<DriveFolder.DriveFolderResult>() {
                    @Override
                    public void onResult(DriveFolder.DriveFolderResult result) {
                        if (!result.getStatus().isSuccess()) {
                            showMessage("Error while trying to create the folder");
                        } else {
                            mThwingAlbertFolderId = result.getDriveFolder().getDriveId();
                            showMessage("Created a folder: " + mThwingAlbertFolderId);
                        }
                    }
                });
            }
        }
    }
});

7 个答案:

答案 0 :(得分:7)

你所看到的,是一个正常的&#39; GDAA的行为,如果您仔细观察&{39; Lifecycle of a Drive file&#39;图(警告:我从未见过源代码,只是从我观察到的内容中假设)。

请参阅GDAA,与REST Api不同,它创建了一个尽力创建缓存和网络流量优化的层。因此,当您从&#39;外部&#39;操纵文件/文件夹时(就像网络应用程序一样),GDAA层在它启动同步之前不知道这个事实,它由它自己的逻辑控制。我自己最初认为GooDrive通过向GDAA发送某种通知来控制它,但显然情况并非如此。此外,一些Google员工提到了'requestSync()' as a cure,但我从未成功地将其发挥作用。

您认为自己正在做的事情是投票GooDrive。但实际上,您正在轮询其DriveId仍然有效(未更新)的GDAA(本地GooPlaySvcs),这与已经消失的真实GooDrive对象不同。

这是文档中没有明确说明的一件事。 GDAA不是最好的Api for EVERY application。它的缓存机制非常适合透明地管理在线/离线状态,网络流量优化。电池续航时间......但在您的情况下,使用REST Api可以 更好,因为您获得的响应反映了当前的GooDrive状态。

我自己遇到了类似的情况,不得不从GDAA切换回REST(并使用基于GCM的私有通知系统替换轮询)。毋庸置疑,通过使用REST Api,您的应用程序变得更加复杂,通常需要同步适配器/服务来执行数据同步,管理网络状态,... GDAA免费提供的所有内容。) 如果您想要并排使用2 api,可以在Github上使用两个相同的CRUD实现(GDAAREST)。

祝你好运

答案 1 :(得分:4)

Google驱动器api不会立即同步,这就是为什么删除的文件夹仍在显示,因此您必须强制使用requestSync()

来强制google驱动器同步
Drive.DriveApi.requestSync(mGoogleApiClient).await();

我在这里提供一个示例代码段: http://wiki.workassis.com/android-google-drive-api-deleted-folder-still-exists-in-query/

答案 2 :(得分:2)

正如Sean所说,Drive Android API在本地缓存元数据以减少带宽和电池使用。

在设备上执行操作时,例如创建文件夹,我们尝试尽快在服务器上应用该操作。虽然由于操作依赖性和内容传输可能会有延迟,但您通常会很快看到服务器上反映的结果。

在服务器上执行操作时,例如通过Web客户端删除文件夹,此操作将在下次Drive Android API同步时反映在设备上。为了节省电池和带宽,同步频率取决于API的使用方式,因为这是用户的优先考虑。

如果您需要保证已发生同步,则可以使用DriveApi.requestSync()明确请求同步并等待结果。目前这个速率限制为每分钟1次,这在测试期间经常受到影响,但对现实世界的使用应该会产生更小的影响。

如果此同步行为导致您的用例出现问题,请告知我们issue tracker,以便我们调查解决方案。

答案 3 :(得分:1)

Google云端硬盘使用自己的生命周期来管理云端硬盘驱动器api并管理缓存中的所有内容,这就是为什么如果您删除某些文件或文件夹并尝试使用谷歌驱动器apis访问它仍然可用,因为它存储在缓存中因此您需要明确然后调用requestSync()方法,然后更新该缓存并为您提供找不到的文件夹或文件。 下面是代码:

Drive.DriveApi.requestSync(mGoogleApiClient).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(@NonNull Status status) {
            Log.e("sync_status", status.toString());
            if (status.getStatus().isSuccess()) {
                setRootFolderDriveId();
            }
        }
    });

并且不要调用Drive.DriveApi.requestSync(mGoogleApiClient).await()因为你的主线程会阻塞所以它会崩溃。使用上面的一个,并在获得成功的回调后,您可以在谷歌驱动器上进行操作,因为它已更新。

答案 4 :(得分:1)

您可以在主线程中执行此操作:

 Drive.DriveApi.requestSync(mGoogleApiClient).setResultCallback(new ResultCallback<com.google.android.gms.common.api.Status>() {
    @Override
    public void onResult(com.google.android.gms.common.api.Status status) {
        if (!status.getStatus().isSuccess()) {
            Log.e("SYNCING", "ERROR" + status.getStatusMessage());
        } else {
            Log.e("SYNCING", "SUCCESS");
            // execute your code to interact with Google Drive

        }
    }
});

答案 5 :(得分:0)

我遇到了同样的问题并使用&#34; Drive.DriveApi.requestSync&#34;做了伎俩。 另外,我建议您查看https://github.com/francescocervone/RxDrive,因为您可以使用rxandroid将同步连接到其他驱动器操作。 例如,这将成为删除和同步操作:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_REFERER} !^$
  RewriteCond %{HTTP_REFERER} !^http://mywebsite.com/my-uploads/my-directory.*$ [NC]
  RewriteRule \.(pdf|doc|docx|odt|rtf|txt)$ [R=302,L]    
</IfModule>

答案 6 :(得分:0)

之所以从查询中列出已删除的文件,是因为Google云端硬盘具有“可搜索”的“垃圾箱”文件夹。您需要先清空垃圾桶。