通过访问令牌创建 GoogleCredential

Create GoogleCredential by Access Token

我想为 Google Drive 设计一个 Android 文件查看器。

起初,我使用GoogleAndroidAPI实现了app,如下,

private void retrieveNextPage(){

    if(mHasMore == false)
        return;

    Query query = new Query.Builder().setPageToken(mNextPageToken).build();
    com.google.android.gms.drive.Drive.DriveApi.query(getGoogleApiClient(), query).setResultCallback(metadataBufferResultResultCallback);

}

但是,Android Drive API 只允许该应用程序查看和获取它自己创建的文件。我无法通过应用程序访问驱动器上的其他文件。

因此,我转向了另一个选择,直接操作Java驱动器API。

根据 Java、

的开发人员指南示例

https://developers.google.com/drive/web/quickstart/quickstart-java

用户必须在浏览器和应用程序之间手动复制和粘贴"Authorization Code",这不是在Android中获取访问令牌的实用方法。

另辟蹊径,我用Android中的GoogleAuthUtil API获取Access Token,恰逢GoogleCredentialDrive 在Java API 中获取文件列表,如下,

private static List<File> retrieveFiles(Drive service) throws IOException{
    List<File> result = new ArrayList<File>();
    Files.List request = service.files().list();
    do {
        try{
            FileList fileList = request.execute();
            result.addAll(fileList.getItems());
            request.setPageToken(fileList.getNextPageToken());

        }catch (IOException e){
            Log.d(dbgT + "JavaRetrieveFiles", "Retrieved Failed");
            request.setPageToken(null);
        }
    }while (request.getPageToken() != null && request.getPageToken().length() > 0);

    return result;
}

private class RetrieveTokenTask extends AsyncTask<String, Void, String>{

    @Override
    protected String doInBackground(String... params){
        String accountName = params[0];
        String scopes = "oauth2:" + "https://www.googleapis.com/auth/drive";
        String token = null;

        try{
            token = GoogleAuthUtil.getToken(getApplicationContext(), accountName, scopes);
        }
        catch (IOException e){
            Log.e(excpTAG, "IO Exception: " + e.getMessage());
        }
        catch (UserRecoverableAuthException e){
            startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
        }
        catch (GoogleAuthException e)
        {
            Log.e(excpTAG, "GoogleAuthException: " + e.getMessage());
        }

        return token;
    }

    @Override
    protected void onPostExecute(String s){
        super.onPostExecute(s);

        //Get Access Token
        Log.d( dbgT + "Token", s);
        EditText tokenText = (EditText) findViewById(R.id.tokenText);
        tokenText.setText(s);

        EditText fileNameText = (EditText) findViewById(R.id.editTextMeta);

        GoogleCredential credential = new GoogleCredential().setAccessToken(s);
        HttpTransport httpTransport = new NetHttpTransport();
        JsonFactory jsonFactory = new JacksonFactory();
        Drive service = new Drive.Builder(httpTransport, jsonFactory, null).setHttpRequestInitializer(credential).build();

        List<File> fileList;
        try{
            fileList = retrieveFiles(service);
            for(int i=0; i< fileList.size(); i++)
                fileNameText.append(fileList.get(i).getTitle());
        }catch(IOException e){
            Log.d(dbgT + "RetrieveFileList", "IO Exception" );
        }

    }
}

不幸的是,当调用 retrieveFiles 中的 request.execute() 时,应用程序总是因 NetworkOnMainThreadException 而崩溃。

我检查了我的访问令牌 s,它通常是 ya29.xxx...etc. 的形式,它也可以传递给我的其他 .NET 程序以从 Google Drive 检索文件.因此我可以确定访问令牌是正确的。

所以我的问题是,如何使用访问令牌创建正确的 Google 凭证,而不是在 setFromTokenResponse 中应用授权码?

提前致谢。

非常感谢Andy的指点,这个问题很简单是主线程上的网络操作引起的,这是一个非常基本的新手错误。

GoogleDrive SDK for Java中的Drive,使用网络库,没有任何background/thread worker,现在我把retrieveFiles()进入背景。

应用Google中的GoogleAuthUtil播放AndroidSDK获取access token,然后[=26=中的GoogleCredential+Drive ] 使用令牌在 Google Drive.

中执行文件操作的 SDK

这是避免 Android SDK 中对 Google Drive 的范围限制的正确方法,允许开发人员获得访问 Google Drive 的完全许可。