新Google Drive Android API(GDAA)中不可靠地报告已删除的文件状态

时间:2014-03-19 18:29:34

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

自新版Google云端硬盘Android Api(GDAA)问世以来,这个问题一直困扰着我。 首先discussed here,我希望它会在以后的版本中消失,但它仍然存在(截至2014/03/19)。用户已删除(指的是'删除'' drive.google.com'中的操作)文件/文件夹一直出现在

  Drive.DriveApi.query(_gac, query), and  
  DriveFolder.queryChildren(_gac, query)

以及

  DriveFolder.listChildren(_gac)

方法,即使与

一起使用
  Filters.eq(SearchableField.TRASHED, false)

查询限定符,或者我在结果上使用过滤构造

for (Metadata md : result.getMetadataBuffer()) {
  if ((md == null) || (!md.isDataValid()) || md.isTrashed()) continue;
  dMDs.add(new DrvMD(md));
}

使用

  Drive.DriveApi.requestSync(_gac);

没有影响。自删除以来所经过的时间变化很大,我的最后一个案例是超过12小时。它完全是随机的。

更糟糕的是,我甚至不能依赖于&drive; google.com'中的EMPTY TRASH,它不会产生任何可预测的结果。有时文件状态更改为' isTrashed()'有时它会从结果列表中消失。

当我不停地摆弄这个问题时,我最终得到了以下superawfulhack:

find file with TRASH status equal FALSE 
if (file found and is not trashed) {
  try to write content
  if ( write content fails)
    create a new file
}

这甚至没有帮助。即使文件位于垃圾箱中,该文件也会显示为健康状态(并且通过查询和元数据测试对其状态进行了双重过滤)。它甚至可以很好地写入垃圾箱中,当它在垃圾箱中检查时,它会被修改。

这里的结论是修复应该获得更高的优先级,因为它使得多平台使用Drive不可靠。开发人员会立即在开发/调试过程中发现它,将它们引导离开。

1 个答案:

答案 0 :(得分:1)

在等待来自support team的任何确认时,我设计了一个HACK,允许解决此问题。使用与SO 22295903中相同的原理,逻辑涉及回退到RESTful API。基本上,删除GDAA的 LIST / QUERY 功能。

高级逻辑是:

  1. 查询RESTful API以检索有问题的文件的ID / ID
  2. 使用检索到的ID通过&fetchDriveId()'
  3. 获取GDAA的DriveId

    以下是记录流程的代码段:

    1 /初始化GDAA' GoogleApiClient' 和RESTful的' services.drive.Drive'

    GoogleApiClient _gac;
    com.google.api.services.drive.Drive _drvSvc;
    
    void init(Context ctx, String email){
      // build GDAA  GoogleApiClient
      _gac = new GoogleApiClient.Builder(ctx).addApi(com.google.android.gms.drive.Drive.API)
        .addScope(com.google.android.gms.drive.Drive.SCOPE_FILE).setAccountName(email)
        .addConnectionCallbacks(ctx).addOnConnectionFailedListener(ctx).build();
      // build RESTFul (DriveSDKv2) service to fall back to  
      GoogleAccountCredential crd = GoogleAccountCredential
      .usingOAuth2(ctx, Arrays.asList(com.google.api.services.drive.DriveScopes.DRIVE_FILE));
      crd.setSelectedAccountName(email);
      _drvSvc = new com.google.api.services.drive.Drive.Builder(
                           AndroidHttp.newCompatibleTransport(), new GsonFactory(), crd).build();
    }
    

    2 /查询云端硬盘RESTful API的方法,返回应用程序使用的GDAA' DriveId。

    String qry = "title = 'MYFILE' and mimeType = 'text/plain' and trashed = false";
    DriveId findObject(String qry) throws Exception {
      DriveId dId = null;
      try {
        final FileList gLst = _drvSvc.files().list().setQ(query).setFields("items(id)").execute();
        if (gLst.getItems().size() == 1) {
          String sId = gLst.getItems().get(0).getId();
          dId = Drive.DriveApi.fetchDriveId(_gac, sId).await().getDriveId();
        } else if (gLst.getItems().size() > 1)
          throw new Exception("more then one folder/file found");
      } catch (Exception e) {}
      return dId;
    }
    

    上面的findObject()方法(为了简单起见,我再次使用' await()'味道)正确地返回Drive对象,反映了已删除的状态,没有明显的延迟(实现在非UI线程中)。

    同样,我强烈建议AGAINST将此代码留在代码中,因为它是一个HACK,对系统的其余部分产生不可预测的影响。