如何通过名称检索DriveFolder?

时间:2014-05-06 16:37:33

标签: android google-drive-android-api

将应用程序连接到云端硬盘后,我创建了一个文件夹。

现在,我想在该文件夹中创建另一个文件夹,但我不知道它的DriveId

@Override
    public void onConnected(Bundle connectionHint) {
        Log.d("DEBUG", "Succesfully connected to Drive.");

        MetadataChangeSet metadata = new MetadataChangeSet.Builder()
                                            .setTitle(getResources().getString(R.string.app_name_short))
                                            .build();

        Drive.DriveApi.getRootFolder(mGoogleApiClient).createFolder(mGoogleApiClient, metadata);

        // Here I would like to retrieve the just created folder and create a subfolder in it

    }

我该如何实现这一目标?

此外,我想提前检查是否已存在具有该名称的文件夹,因为上面的代码正在每个连接上创建一个新文件夹。而Drive似乎允许创建许多具有相同名称的文件夹。

3 个答案:

答案 0 :(得分:0)

设置创建完成后要调用的ResultCallback,您可以在其中传递ContentsResult

文档中的示例如下:

public class CreateFileActivity {

    // ...

    ResultCallback<ContentsResult> contentsCallback = new
            ResultCallback<ContentsResult>() {
        @Override
        public void onResult(ContentsResult result) {
            if (!result.getStatus().isSuccess()) {
                // Handle error
                return;
            }

            MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                    .setTitle("New file")
                    .setMimeType("text/plain").build();
            // Create a file in the root folder
            Drive.DriveApi.getRootFolder(getGoogleApiClient())
                    .createFile(getGoogleApiClient(), changeSet, result.getContents())
                    .addResultCallback(this);
        }
    }
}

答案 1 :(得分:0)

这是一个&#39; await&#39;解决方案的版本(为简单起见 - 必须在非UI线程上运行)(GoogleApiClient的初始化/连接是标准的,可以在其他地方找到):

  static final String MIMEFLDR  = "application/vnd.google-apps.folder";
  private GoogleApiClient  _gac;

  DriveFolder myFldr = getOrCreateFldr(null, "myFolder");
  DriveFolder myChildFldr = getOrCreateFldr(myFldr, "myChildFolder");

  private DriveId findFirst(String title, String mime, DriveFolder fldr) {
    ArrayList<Filter> fltrs = new ArrayList<Filter>();
    fltrs.add(Filters.eq(SearchableField.TRASHED, false));
    if (title != null)  fltrs.add(Filters.eq(SearchableField.TITLE, title));
    if (mime  != null)  fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
    Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build(); 
    MetadataBufferResult rslt = (fldr == null) ? Drive.DriveApi.query(_gac, qry).await() : 
                                                   fldr.queryChildren(_gac, qry).await();
    MetadataBuffer mdb = null;
    if (rslt.getStatus().isSuccess()) try {
      mdb = rslt.getMetadataBuffer();
      for (Metadata md : mdb) {
        if ((md == null) || (!md.isDataValid()) || md.isTrashed()) continue;
        return md.getDriveId();
      }
    } catch (Exception e) {}
    finally { if (mdb != null) mdb.close(); } 
    return null;
  }

  private DriveFolder getOrCreateFldr(DriveFolder fldr, String titl) {
    DriveFolder df = null;
    try {
      DriveId dId = findFirst(titl, MIMEFLDR, fldr);
      if (dId != null) {                 // exists
        df = Drive.DriveApi.getFolder(_gac, dId);
      } else {                           // doesn't exist, create in folder / root
        df = createFldr((fldr == null) ? Drive.DriveApi.getRootFolder(_gac) : fldr,  titl);
      }
    } catch (Exception e) {UT.le(e);}
    return df;
  }

  private DriveFolder createFldr(DriveFolder fldr, String name) {
    DriveFolder drvFldr = null;
    try { 
      MetadataChangeSet meta = 
              new MetadataChangeSet.Builder().setTitle(name).setMimeType(MIMEFLDR).build();
      drvFldr = fldr.createFolder(_gac, meta).await().getDriveFolder();
    } catch (Exception e) {}
    return drvFldr;
  }

它很容易变成回调版本,但看起来会很混乱。但是要小心使用findFirst()方法,Google Drive允许多个具有相同名称的文件/文件夹(因为只有ResourceId / DriveId是唯一标识符)。

如果您想深入挖掘,可以在此GitHub project中显示递归文件夹创建。

答案 2 :(得分:0)

我尝试整合了几个答案,并添加了我的部分以获得一个有效的方法。肯定会有比我开发的更优雅和封装的方式,但它是我现在能提供的最好的。

从元数据中获取 DriveId 对象后,接下来是使用 asDriveFolder()方法获取 DriveFolder 对象。< / p>

感谢@ Bikesh M Annur和@ seanpj,他们在How to get DriveId of created folder in Google Drive Android API中做出了贡献。

private DriveFolder mFolder;

private void getDriveFolder(String folderName) {

    Query query = new Query.Builder().addFilter(Filters.and(
            Filters.eq(SearchableField.TITLE, folderName),
            Filters.eq(SearchableField.TRASHED, false))).build();

    getDriveResourceClient().query(query).addOnSuccessListener(new OnSuccessListener<MetadataBuffer>() {
        @Override
        public void onSuccess(MetadataBuffer metadata) {
            mFolder = null;

            for (Metadata md : metadata) {
                if (md == null) continue;
                DriveId dId  = md.getDriveId();      // here is the "Drive ID"
                String title = md.getTitle();
                String mime  = md.getMimeType();

                if (md.isFolder()) {
                    mFolder = dId.asDriveFolder();   // Returns the "DriveFolder" object
                    break;
                }
            }

            if (mFolder != null) {
                // Or better from here you can take your actions
                //...
            }
        }
    });
}

注意:请注意,在Google云端硬盘中,您可以多次创建具有相同名称的文件夹。此例程将从列表中返回第一个例程。由您来检测您想要采取的所有重复中的哪一个。