如何将GoogleAuthorizationCodeFlow与AccessType配合使用处于离线状态

问题描述:

我必须实现将文件上传到Google云端硬盘的功能。
如在Quick Start指南。如何将GoogleAuthorizationCodeFlow与AccessType配合使用处于离线状态

首先,我调用generateLinkAuth来生成链接来获取代码。
然后执行generateCode来获取令牌。
一切都很好。

List<String> SCOPES = Arrays.asList("https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/userinfo.email", 
      "https://www.googleapis.com/auth/userinfo.profile", DriveScopes.DRIVE); 
    public String generateLinkAuth() { 
      mHttpTransport = new NetHttpTransport(); 
      mJsonFactory = new JacksonFactory(); 

      mFlow = new GoogleAuthorizationCodeFlow.Builder(mHttpTransport, mJsonFactory, CLIENT_ID, CLIENT_SECRET, SCOPES).setAccessType("online").setApprovalPrompt("force").build(); 


      String url = mFlow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build(); 

      System.out.println("url :" + url); 
      return url; 
     } 

     public void generateCode(String code) { 
      new GetCredentialFromCode(mContext, code).execute(); 
     } 


     class GetCredentialFromCode extends AsyncTask<Void, Void, Void> { 
      private Context mContext; 
      private String code; 
      private final ProgressDialog mDialog; 

      public GetCredentialFromCode(Context context, String cd) { 
       mContext = context; 
       mDialog = new ProgressDialog(context); 
       mDialog.show(); 
       mDialog.setTitle("Uploading ..."); 
       code = cd; 
      } 

      @Override 
      protected Void doInBackground(Void... params) { 

       if (mFlow != null) { 
        try { 

         mResponse = mFlow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute(); 

         mCredential = new GoogleCredential(); 

         mCredential.setFromTokenResponse(mResponse); 


         String accessToken = mCredential.getAccessToken(); 
         Editor edit = mPrefs.edit(); 
         edit.putString(GOOGLE_DRIVE_TOKEN, accessToken); 
         edit.commit(); 

         String accessTokenSave = mPrefs.getString(GOOGLE_DRIVE_TOKEN, "NO KEY"); 
         Log.e(TAG, "access Token Saved is " + accessTokenSave); 

        } catch (IOException e) { 
         Editor edit = mPrefs.edit(); 
         edit.putString(GOOGLE_DRIVE_TOKEN, "NO KEY"); 
         e.printStackTrace(); 
        } 
       } 

       String accessTokenSave = mPrefs.getString(GOOGLE_DRIVE_TOKEN, "NO KEY"); 

       mHttpTransport = new NetHttpTransport(); 
       mJsonFactory = new JacksonFactory(); 
       mCredential = new GoogleCredential().setAccessToken(accessTokenSave); 

       getUserInfo(); 

       mDriveService = new Drive.Builder(mHttpTransport, mJsonFactory, mCredential).build(); 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Void result) { 
       mDialog.dismiss(); 
       GoogleDriveLogInAct act= (GoogleDriveLogInAct) mContext; 
       act.goBackSettingScreen(); 
      } 

     } 

的问题是,令牌将在1小时内到期,setAccessType(“在线”),所以我将其更改为setAccessType(“离线”)。
当我改变它,并再次运行我的Android应用程序时,我得到一个错误 - 当我执行下面的代码。

   mResponse = mFlow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute(); 

       mCredential = new GoogleCredential(); 

       mCredential.setFromTokenResponse(mResponse); 

当我尝试调试在控制台上执行mCredential.setFromTokenResponse(mResponse)。,会引发异常

java.lang.RuntimeException: An error occured while executing doInBackground() 
    at android.os.AsyncTask$3.done(AsyncTask.java:278) 
    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
    at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
    at java.lang.Thread.run(Thread.java:856) 
Caused by: java.lang.IllegalArgumentException: Please use the Builder and call setJsonFactory, setTransport and setClientSecrets 
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:88) 
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.setRefreshToken(GoogleCredential.java:294) 
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.setRefreshToken(GoogleCredential.java:153) 
    at com.google.api.client.auth.oauth2.Credential.setFromTokenResponse(Credential.java:556) 
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.setFromTokenResponse(GoogleCredential.java:313) 
    at com.jp.shotdocs.libs.GoogleDriveLib$GetCredentialFromCode.doInBackground(GoogleDriveLib.java:168) 
    at com.jp.shotdocs.libs.GoogleDriveLib$GetCredentialFromCode.doInBackground(GoogleDriveLib.java:1) 
    at android.os.AsyncTask$2.call(AsyncTask.java:264) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
    ... 4 more 

如何使用accessType离线?
有什么我必须修改使用此模式?

+1

我已经解决了这个问题...我应该使用GoogleCredential.Build()而不是新的GoogleCredential()声明GoogleCredential。 – quantm

+1

请发表一篇评论,而不是评论,否则问题仍然存在未答复部分 – rds

+0

以我的理解,请检查我是否正确。 – Bharathi

(在评论中回答见Question with no answers, but issue solved in the comments (or extended in chat)

的OP写道:

有解决这个问题......我应该用GoogleCredential.Build()代替new GoogleCredential()声明GoogleCredential