在新的Google Drive Android API(GDAA)中不可靠地报告了已删除的文件状态 [英] Deleted files status unreliably reported in the new 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 功能。
高级逻辑是:
- 查询RESTful API以检索有问题的文件的ID / ID
- 使用检索的ID通过'fetchDriveId获取GDAA的DriveId( )'
这里是代码片段来记录过程:
1 /初始化GDAA的'GoogleApiClient'和RESTful的'services.drive.Drive'
$ bGoogleApiClient _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:
- query the RESTful API to retrieve the ID/IDs of file(s) in question
- 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屋!