acs-team
acs-team

Reputation: 612

Google Drive REST API connection TimeOut?

I'm using Drive REST Api (Not Google Drive Android API) and i got oftenly a time-out (+- each 5 request) when i send a request to Google drive. It can appear when i list a folder or when i download a file, but only when i make the request. Never during a download.

For the test, i use a Wifi connection. No problem with the internet connection.

I create the connection like describes in the documentation (https://developers.google.com/drive/web/quickstart/android). Here is the code:

googleAccountCredential = GoogleAccountCredential.usingOAuth2(activity, Arrays.asList(DriveScopes.DRIVE_FILE));

if (accountName.length() == 0) {
    activity.startActivityForResult(googleAccountCredential.newChooseAccountIntent(), ResultCode.GOOGLE_DRIVE_ACCOUNT_NAME_RESULT_CODE);
    return false;
} else {
    if (!isConnected) {
        googleAccountCredential.setSelectedAccountName(accountName);
        googleAccountCredential.setBackOff(new ExponentialBackOff());

        driveService = new Drive.Builder(AndroidHttp.newCompatibleTransport(), JacksonFactory.getDefaultInstance(), googleAccountCredential)
                .setApplicationName(activity.getString(R.string.app_name))
                .build();

        isConnected = true;
    }

    return true;
}

So if i don't have the "account name", i ask it, otherwise i create the connection only one time! (I tried to create the connection each time, but it doesn't change anything)

All request are made in an asyncTask.

Sometime it works and sometime not.

Request Time-out exemple :

1.

request = driveService.files().list();
request.setQ("root in parents AND trashed = false");
fileList = request.execute();// Time-out

2.

HttpResponse resp = driveService.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();// Time-out

EDIT:

Here is the dump:

W/System.err: java.net.SocketTimeoutException: timeout
W/System.err: at com.android.okhttp.okio.Okio$3.newTimeoutException(Okio.java:207)
W/System.err: at com.android.okhttp.okio.AsyncTimeout.exit(AsyncTimeout.java:250)
W/System.err: at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:217)
W/System.err: at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
W/System.err: at com.android.okhttp.okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
W/System.err: at com.android.okhttp.okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
W/System.err: at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
W/System.err: at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:788)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
W/System.err: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java)
W/System.err: at com.google.api.client.http.javanet.NetHttpResponse.<init>(NetHttpResponse.java:37)
W/System.err: at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:94)
W/System.err: at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:972)
W/System.err: at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
W/System.err: at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
W/System.err: at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
W/System.err: at org.team.acs.scubalog.share.cloud.googleDrive.asynckTask.GoogleDriveGetDirectoryListAsyncTask.doInBackground(GoogleDriveGetDirectoryListAsyncTask.java:60)
W/System.err: at org.team.acs.scubalog.share.cloud.googleDrive.asynckTask.GoogleDriveGetDirectoryListAsyncTask.doInBackground(GoogleDriveGetDirectoryListAsyncTask.java:20)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err: at java.lang.Thread.run(Thread.java:818)

Any idea?

Upvotes: 1

Views: 4630

Answers (2)

C&#237;cero Moura
C&#237;cero Moura

Reputation: 2323

For others with this problem, this worked to me:

    private static HttpRequestInitializer setHttpTimeout(final HttpRequestInitializer requestInitializer) {
            return new HttpRequestInitializer() {
                @Override
                public void initialize(HttpRequest httpRequest) throws IOException {
                    requestInitializer.initialize(httpRequest);
                    httpRequest.setConnectTimeout(3 * 60000);  // 3 minutes connect timeout
                    httpRequest.setReadTimeout(3 * 60000);  // 3 minutes read timeout
                }
            };
        }


 @Nullable
    public static DriveServiceHelper create(Context context) {

        Set<Scope> requiredScopes = new HashSet<>(2);
        requiredScopes.add(new Scope(DriveScopes.DRIVE_APPDATA));
        requiredScopes.add(new Scope(DriveScopes.DRIVE_FILE));

        GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(context);
        if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {




            // Use the authenticated account to sign in to the Drive service.
            GoogleAccountCredential credential =
                    GoogleAccountCredential.usingOAuth2(context, Collections.singleton(DriveScopes.DRIVE_APPDATA));
            credential.setSelectedAccount(signInAccount.getAccount());
            com.google.api.services.drive.Drive googleDriveService =
                    new com.google.api.services.drive.Drive.Builder(
                            AndroidHttp.newCompatibleTransport(),
                            new GsonFactory(),
                            setHttpTimeout(credential))
                            .setApplicationName(context.getString(R.string.app_name))
                            .build();

            return new DriveServiceHelper(googleDriveService);
        }

        return null;
    }

Reference: https://developers.google.com/api-client-library/java/google-api-java-client/errors

Upvotes: 5

seanpj
seanpj

Reputation: 6755

I don't see anything apparently incorrect in your code, as a matter of fact, I've successfully used VERY similar construct:

  com.google.api.services.drive.Drive driveService =
    new Drive.Builder(
      AndroidHttp.newCompatibleTransport(),
      new GsonFactory(),
      GoogleAccountCredential
        .usingOAuth2(activity.getApplicationContext(), Collections.singletonList(DriveScopes.DRIVE_FILE))
        .setSelectedAccountName(accountName)
  ).build();

So, let;s take a look at the differences (not saying that this is the fix):

1/ I don't specify the '.setBackOff(new ExponentialBackOff())' strategy

2/ I use 'activity.getApplicationContext()' instead of activity context

3/ I don't know where is your user email (accountName) coming from. It has to be one of the accounts registered on the device which can be achieved through:

  • standard Android Settings > Accounts menu > Add account
  • not specifying the 'setSelectedAccountName(accountName)', which causes the account picker to pop-up, allowing the user to select the registered account or add a new one
  • invoking Account picker in your activity and getting the email from 'onActivityResult'

The point 3/ is very likely NOT causing your problem, it would return a different error message.

All of this can be seen in the RESTDemo here (see REST.init() and REQ_ACCPICK) .

Good Luck

Upvotes: 0

Related Questions