I am implementing the Google Drive APIs in my android application. I do not want to use PendingResult#setResultCallback(), rather, I want to use PendingResult#await() so I can get the result in the next line and not have to wait. This isn't an issue because everything is running in the background.
However, every time I call await(), I get the following error. I have tried running a single call to the Google Drive API that uses await() in an AsyncTask, Thread, IntentService, Service with AsyncTask, and a Service with a Thread. I have received the following error every time. I tried calling Looper.prepare() in my Thread implementations, but it didn't solve anything.
Has anyone else ran into this issue?
java.lang.IllegalStateException: await must not be called on the UI thread
at com.google.android.gms.internal.hm.a(Unknown Source)
at com.google.android.gms.common.api.a$a.await(Unknown Source)
at [OMITTED].GoogleDriveManager$2.onConnected(GoogleDriveManager.java:83)
at com.google.android.gms.internal.hc.c(Unknown Source)
at com.google.android.gms.common.api.c.eK(Unknown Source)
at com.google.android.gms.common.api.c.d(Unknown Source)
at com.google.android.gms.common.api.c$2.onConnected(Unknown Source)
at com.google.android.gms.internal.hc.c(Unknown Source)
at com.google.android.gms.internal.hc.cp(Unknown Source)
at com.google.android.gms.internal.hb$h.b(Unknown Source)
at com.google.android.gms.internal.hb$h.d(Unknown Source)
at com.google.android.gms.internal.hb$b.fv(Unknown Source)
at com.google.android.gms.internal.hb$a.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
at dalvik.system.NativeStart.main(Native Method)
This is the code I am using to test the API:
apiClient = new GoogleApiClient.Builder(mContext)
.addApi(Drive.API)
.addScope(Drive.SCOPE_APPFOLDER)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
LogUtil.log(TAG, "onConnected()");
connected = true;
DriveApi.ContentsResult result = Drive.DriveApi.newContents(apiClient).await();
}
@Override
public void onConnectionSuspended(int i) {
LogUtil.log(TAG, "onConnectionSuspended()");
connected = false;
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult result) {
LogUtil.log(TAG, "onConnectionFailed()");
connected = false;
}
})
.build();
apiClient.connect();
apiClient.connect()
is an asynchronous operation, hence why calling it within an AsyncTask does not help (running connect on a background thread doesn't help when onConnected()
is being called on the UI thread).
Instead, you could start an AsyncTask from your onConnected()
callback - that AsyncTask's doInBackground()
could then call Drive.DriveApi.newContents(apiClient).await()
.
Of course, there's no need to ever call await()
- use setResultCallback() to asynchronously wait for newContents()
to complete:
@Override
public void onConnected(Bundle bundle) {
LogUtil.log(TAG, "onConnected()");
connected = true;
Drive.DriveApi.newContents(apiClient).setResultCallback(
new ResultCallback<DriveApi.ContentsResult>() {
@Override
public void onResult(DriveApi.ContentsResult result) {
// Use result
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With