Android:使用Google Drive API将文件复制到Google云端硬盘 - 最佳方法是什么?

时间:2017-03-25 12:23:03

标签: android google-drive-api

我需要从Android App将文件复制到Google云端硬盘。考虑将4-5 MB文件大小复制到根文件夹。

已经完成了here的一些示例代码。

有人可以查看以下流程,并告诉我这是否是最佳方法。我怀疑是因为这种方法

1)必须使用许多回调,这使得代码逻辑不那么直接

2)使用outputStreamwriter.write()方法进行文件复制操作,而不是像API方法这样的副本

我不是说我经历的演示是不正确的,但是不想错过任何更好的方法,如果周围存在......我也有可能忽略了一些事情......并且选择了错误的例子...... / p>

以下是我发现的流程,并希望与某些Google云端硬盘API专家核实..

1)用户授权和连接后:调用newDriveContents API

Drive.DriveApi.getRootFolder(getGoogleApiClient()).createFile(getGoogleApiClient(), changeSet, driveContents).setResultCallback(fileCallback);

2)DriveContentsResult回调 - 调用创建文件,并使用输出流写入来创建或复制文件           OutputStreamWriter.write ( file contents )

driveContents将来自Drive.DriveApi.getRootFolder(getGoogleApiClient()).createFile(getGoogleApiClient(), changeSet, driveContents).setResultCallback(fileCallback);

3)DriveFileResult回调 - 检查成功或失败           $('. elem:eq(2)')

注意:我没有在上面的伪代码中使用try / catch和新的Thread(){}来使它变得小巧可读...

2 个答案:

答案 0 :(得分:0)

如果是重构问题,我会这样做:

public class GoogleDrive implements DriveProvider  
{
   private String contents;
   private ArrayList<Result> results;
   private GoogleApiClient googleApiClient;

   public GoogleDrive(GoogleApiClient googleApiClient){
      ArrayList<Result> results = new ArrayList<Result>();
      this.googleApiClient = googleApiClient;
   }

   public ArrayList<Result> upload(String contents){
       this.contents = contents;
       Drive.DriveApi.newDriveContents(this.googleApiClient).setResultCallback(driveContentsCallback);
   }

   final private ResultCallback<DriveContentsResult> driveContentsCallback = new
        ResultCallback<DriveContentsResult>() {
    @Override
    public void onResult(DriveContentsResult result) {
        if (!result.getStatus().isSuccess()) {
            results.add(new Result("Error while trying to create new file contents", true));
            return;
        }
        final DriveContents driveContents = result.getDriveContents();

        // Perform I/O off the UI thread.
        new Thread() {
            @Override
            public void run() {
                // write content to DriveContents
                OutputStream outputStream = driveContents.getOutputStream();
                Writer writer = new OutputStreamWriter(outputStream);
                try {
                    writer.write(this.contents);
                    writer.close();
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                }

                MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                        .setTitle("New file")
                        .setMimeType("text/plain")
                        .setStarred(true).build();

                // create a file on root folder
                Drive.DriveApi.getRootFolder(this.googleApiClient)
                        .createFile(this.googleApiClient, changeSet, driveContents)
                        .setResultCallback(fileCallback);
            }
        }.start();
    }
};

final private ResultCallback<DriveFileResult> fileCallback = new
        ResultCallback<DriveFileResult>() {
    @Override
    public void onResult(DriveFileResult result) {
        if (!result.getStatus().isSuccess()) {
            results.add(new Result("Error while trying to create the file", true));
            return;
        }
        results.add(new Result("Created a file with content: " + result.getDriveFile().getDriveId(), false));
    }
};
}

public interface DriveProvider {
   public ArrayList<Result> upload(String contents);
}

public class Result{
private String message;
private boolean error;

public Result(String message, boolean error){
    this.message = message;
    this.error = error;
}

public String getMessage(){
    return this.message;
}

public boolean isError(){
    return this.error;
}
}

用法:

@Override
public void onConnected(Bundle connectionHint) {
    super.onConnected(connectionHint);

    DriveProvider driverProvider = new GoogleDrive(getGoogleApiClient()); //This should be Injected using IoC container

    ArrayList<Result> results = driverProvider.upload("Hello World");

    for(Result result : results){
        showMessage(result.getMessage()); //isError could be used to change application flow by firing an Intent if all message are not errored.
    }
}

将类和接口放在单独的文件中会更好。 这种实现方式使您的应用程序依赖抽象而不是具体实现,并将Google Drive逻辑与UI分开。

希望这能回答你的问题。

答案 1 :(得分:0)

完成应用与Google Drive SDK的集成后,我可以说这是最佳方法,因为

1)调用Google驱动SDK必须是异步的。因为它是异步的,所以需要回调

2)对于往返Google云端硬盘的复制操作,没有可用的直接复制方法。必须使用android标准outputStreamwriter和inputStreamWriter

还有另一种可用的同步方法,如下所示,但除了删除操作

之外,Google不推荐使用它

DriveApi.DriveContentsResult driveContentsResult = backupDriveFile.open(googleApiClient,DriveFile.MODE_READ_ONLY,null).await() ;