5

この問題は、新しい Google Drive Android Api (GDAA) の開始以来、私を悩ませてきました。最初にここで説明しましたが、後のリリースでなくなることを願っていましたが、まだ残っています (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()' に変更される場合があり、結果リストから消える場合があります。

この問題をいじり続けていたので、次のスーパーハックに行き着きました。

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
}

これでも役に立ちません。ファイルがごみ箱にある場合でも、ファイルは正常であると表示されます (そのステータスは、クエリとメタデータ テストによって二重にフィルター処理されます)。喜んで書き込むこともでき、ゴミ箱で検査すると変更されます。

ここでの結論は、マルチプラットフォームでのドライブの使用が信頼できなくなるため、修正の優先度を高くする必要があるということです。開発/デバッグプロセスで開発者がすぐに発見し、彼らを遠ざけます。

4

1 に答える 1

1

サポート チームからの確認を待っている間に、この問題を回避できる HACK を考案しました。SO 22295903と同じ原則を使用して、ロジックには RESTful API へのフォールバックが含まれます。基本的に、GDAAのLIST / QUERY機能を削除します。

高レベルのロジックは次のとおりです。

  1. RESTful API をクエリして、問題のファイルの ID を取得します
  2. 取得した ID を使用して、「fetchDriveId()」を介して 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/ Drive 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 スレッドで実装)。

繰り返しますが、これはシステムの残りの部分に予測できない影響を与えるハックであるため、これを必要以上に長くコードに残すことは絶対に避けてください。

于 2014-03-22T17:19:58.150 に答える