【问题标题】:How to download file from Google Drive using Drive.API?如何使用 Drive.API 从 Google Drive 下载文件?
【发布时间】:2015-06-12 05:42:33
【问题描述】:

我正在使用 Google Drive.Api 以使用户的应用数据与用户驱动器帐户同步。

用户数据库是 sqlite 数据库格式。我已成功将二进制文件上传到驱动器,但无法从应用程序内下载文件。

我如何获得文件 URl:

  final GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE_FILE));
    credential.setSelectedAccountName(accountName);
    service = new com.google.api.services.drive.Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();

    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, "BackupFile"))
            .build();


    final DriveFolder folder = Drive.DriveApi.getRootFolder(mGoogleApiClient);
    folder.queryChildren(mGoogleApiClient, query).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
        @Override
        public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
            final MetadataBuffer metadataBuffer = metadataBufferResult.getMetadataBuffer();
            int iCount = metadataBuffer.getCount();

            if (iCount == 1) {
                Log.i("Tag", "file was found");
                final DriveId myFileId = metadataBuffer.get(0).getDriveId();
                final DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, myFileId);

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        DriveResource.MetadataResult mdRslt = file.getMetadata(mGoogleApiClient).await();
                        if (mdRslt != null && mdRslt.getStatus().isSuccess()) {
                            String link = mdRslt.getMetadata().getWebContentLink();
                            Log.d("TAG", "Link to File:" + link);
                             DownloadBackup(link);
                        }
                    }
                }).start();

            }
            metadataBuffer.release();
        }
    });

尝试通过以下方式下载文件:

public void DownloadBackup(String url){
        InputStream mInput=null;
        FileOutputStream mOutput=null;
        if(url != null && url.length() > 0 ){
        try {
                GoogleAccountCredential crd = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE_FILE));
                crd.setSelectedAccountName(accountName);
                com.google.api.services.drive.Drive srv = new com.google.api.services.drive.Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), crd).build();
                mInput = srv.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute().getContent();
                String outFileName = getApplicationContext().getDatabasePath(DatabaseHandler.DATABASE_NAME).getPath();
                mOutput = new FileOutputStream(outFileName);
                byte[] mBuffer = new byte[1024];
                int mLength;
                while ((mLength = mInput.read(mBuffer)) > 0) {
                    mOutput.write(mBuffer, 0, mLength);
                }
                mOutput.flush();
                Log.d("TAG", "Successfully Downloaded contents");
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    //Close the streams
                    if(mOutput != null){
                        mOutput.close();
                    }
                    if(mInput != null){
                        mInput.close();
                    }
                } catch (IOException e) {
                    Log.e("Tag", "failed to close databases");
                }
            }
        } else {
            // The file doesn't have any content stored on Drive.
            // return null;
            Log.e("Tag", "No content on Drive");
        }
    }

错误日志:

W/System.err﹕ com.google.api.client.http.HttpResponseException: 401 Unauthorized
W/System.err﹕ <HTML>
W/System.err﹕ <HEAD>
W/System.err﹕ <TITLE>Unauthorized</TITLE>
W/System.err﹕ </HEAD>
W/System.err﹕ <BODY BGCOLOR="#FFFFFF" TEXT="#000000">
W/System.err﹕ <H1>Unauthorized</H1>
W/System.err﹕ <H2>Error 401</H2>
W/System.err﹕ </BODY>
W/System.err﹕ </HTML>
W/System.err﹕ [ 06-12 11:01:05.447 26208:26236 W/System.err ]
        at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1061)
W/System.err﹕ at com.example.app.activities.Main.DownloadBackup(Main.java:487)
W/System.err﹕ at com.example.app.activities.Main$15$1.run(Main.java:332)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)

【问题讨论】:

标签: android sqlite google-drive-api google-drive-android-api


【解决方案1】:

这是我成功的方法。我没有保存“getWebContentLink”的结果,而是保存了一个文件/文件夹 ID(它是一个字符串)。并将此 ID 传递给类似这样的方法:

 /*************************************************************************
   * get file contents
   * @param resId  file driveId
   * @return       file's content  / null on fail
   */
  static InputStream read(String resId) {
    if (mGOOSvc != null && mConnected && resId != null) try {
      File gFl = mGOOSvc.files().get(resId).setFields("downloadUrl").execute();
      if (gFl != null){
        String strUrl = gFl.getDownloadUrl();
        return mGOOSvc.getRequestFactory()
        .buildGetRequest(new GenericUrl(strUrl)).execute().getContent();
      }
    } catch (Exception e) { /* error handling */ }
    return null;
  }

检索“downloadURL”并获取内容。这个method 的完整上下文可以在here 看到。

祝你好运

【讨论】:

  • ... 我猜您也可以检索/保存/使用“downloadUrl”字符串,但 ID (ResourceID) 实体被视为主要标识符。
  • 文件 gFl = mGOOSvc.files().get(resId).setFields("downloadUrl").execute();不执行。即使满足“if (mGOOSvc != null && mConnected && resId != null)”条件。
  • 我将“不执行”理解为“不返回”。如果是这种情况,则服务器没有响应。您是否尝试过制定参数(并对其进行测试)here (bottom of the page)
  • 根据上述 Ofir 的评论,您将 GDAA 与 REST 混合使用。可能但很危险(延迟/时间)。查看GDAAREST CRUD 实现之间的区别。注意DriveId and ResourceID之间的区别
  • 好像我在使用 Drive.Id 和你的方法。我使用了 ResourceId 并且文件已成功下载。非常感谢 :D 但现在我有另一个问题,下载的文件不包含原始 .db 文件所包含的内容。
猜你喜欢
  • 1970-01-01
  • 2013-09-04
  • 2020-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多