在新的Google Drive Android API(GDAA)中不可靠地报告了已删除的文件状态 [英] Deleted files status unreliably reported in the new Google Drive Android API (GDAA)

查看:168
本文介绍了在新的Google Drive Android API(GDAA)中不可靠地报告了已删除的文件状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从新版Google Drive Android Api(GDAA)诞生以来,这个问题一直困扰着我。
首先在这里讨论,我希望它能在后续版本中消失,但它仍然存在(截至2014/03/19)。

 <$ c中的用户被删除(指的是'drive.google.com'中的'删除'操作)文件/文件夹$ c> Drive.DriveApi.query(_gac,query)和
DriveFolder.queryChildren(_gac,query)

以及

  DriveFolder.listChildren(_gac)



方法,即使与

 过滤器一起使用。 eq(SearchableField.TRASHED,false)

查询限定符,或者对结果使用过滤结构(元数据md:result.getMetadataBuffer()){
如果((md == null)||

  (!md.isDataValid())|| md.isTrashed())continue; 
dMDs.add(new DrvMD(md));

使用

  Drive.DriveApi.requestSync(_gac); 

没有任何影响。而去除后的时间差异很大,我的最后一个案例超过了12小时。它完全是随机的。

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



当我一直处理这个问题时,我最终得到了以下superawfulhack:

 找到TRASH状态的文件等于FALSE 
if(找到并且未被删除的文件){
如果(写入内容失败)尝试写入内容

创建一个新文件
}

这甚至都没有帮助。即使文件位于垃圾桶中(文件的状态由查询和元数据测试双重过滤),该文件也显示为健康。它甚至可以很高兴地写入垃圾箱并在垃圾箱中检查时进行修改。



这里的结论是修复应该具有更高的优先级,平台使用的驱动器不可靠。开发人员马上会在开发/调试过程中发现它,并将其引导出去。 当您等待 rel =nofollow noreferrer> support team ,我设计了一个HACK来解决这个问题。使用与相同的原则SO 22295903 ,该逻辑涉及回退到RESTful API。基本上,删除GDAA的 LIST / QUERY 功能。



高级逻辑是:


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

这里是代码片段来记录过程:

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

  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( );
//建立RESTFul(DriveSDKv2)服务以回退至
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 /查询Drive RESTful API的方法,返回要使用的GDAA的DriveId

pre $ 字符串qry =title ='MYFILE'和mimeType ='text / plain'和trashed = false ;
DriveId findObject(String qry)抛出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)
抛出新的异常(多于一个文件夹/找到的文件);
} catch(Exception e){}
return dId;



$ b

上面的findObject()方法(同样我使用'await )'为了简单起见)简单地返回Drive对象,反映了没有明显延迟的垃圾状态(在非UI线程中实现)。



同样,我强烈建议AGAINST将代码留在比necassary更长的时间,因为它对系统的其他部分有不可预知的影响。 $ b

This issue has been bugging me since the inception of the new Google Drive Android Api (GDAA). First discussed here, I hoped it would go away in later releases, but it is still there (as of 2014/03/19). The user-trashed (referring to the 'Remove' action in 'drive.google.com') files/folders keep appearing in both the

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

as well as

  DriveFolder.listChildren(_gac)

methods, even if used with

  Filters.eq(SearchableField.TRASHED, false)

query qualifier, or if I use a filtering construct on the results

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

Using

  Drive.DriveApi.requestSync(_gac);

has no impact. And the time elapsed since the removal varies wildly, my last case was over 12 HOURS. And it is completely random.

What's worse, I can't even rely on EMPTY TRASH in 'drive.google.com', it does not yield any predictable results. Sometime the file status changes to 'isTrashed()' sometimes it disappears from the result list.

As I kept fiddling with this issue, I ended up with the following 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
}

Not even this helps. The file shows up as healthy even if the file is in the trash (and it's status was double-filtered by query and by metadata test). It can even be happily written into and when inspected in the trash, it is modified.

The conclusion here is that a fix should get higher priority, since it renders multi-platform use of Drive unreliable. It will be discovered by developers right away in the development / debugging process, steering them away.

解决方案

While waiting for any acknowledgement from the support team, I devised a HACK that allows a workaround for this problem. Using the same principle as in SO 22295903, the logic involves falling back to RESTful API. Basically, dropping the LIST / QUERY functionality of GDAA.

The high level logic is:

  1. query the RESTful API to retrieve the ID/IDs of file(s) in question
  2. use retrieved ID to get GDAA's DriveId via 'fetchDriveId()'

here are the code snippets to document the process:

1/ initialize both GDAA's 'GoogleApiClient' and RESTful's '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/ method that queries the Drive RESTful API, returning GDAA's DriveId to be used by the app.

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;
}

The findObject() method above (again I'm using the 'await()' flavor for simplicity) returns the the Drive objects correctly, reflecting the trashed status with no noticeable delay (implement in non-UI thread).

Again, I would strongly advice AGAINST leaving this in code longer than necassary since it is a HACK with unpredictable effect on the rest of the system.

这篇关于在新的Google Drive Android API(GDAA)中不可靠地报告了已删除的文件状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆