Migrating from PlusClient to GoogleApiClient
Version 4.2 of Google Play Services introduced a new replacement for PlusClient
, GoogleApiClient. While PlusClient
is still present, it will be removed in a future version so its a good idea to upgrade when possible. The new class has been designed based on feedback from developers across various Google Play services APIs, and provides a much more consistent, powerful base.
PlusClient
was reasonably straightforward for developers implementing just Google+ Sign-In. Unfortunately, anyone looking to combine multiple services together quickly realised that managing a series of callbacks for all the different connections was way too painful. GoogleApiClient
solves that by providing one central client to connect or disconnect. It allows multiple APIs to be added to a connection for Google+, Drive, Games, and the other services available.
Replacing PlusClient
with GoogleApiClient
isn’t too hard, and if you are using multiple clients makes life gets a lot easier - you don’t have to worry about what order to start clients in, and a much more consistent and simple workflow for calls to different services.
Building the client
The GoogleApiClient
should be constructed in precisely the same place as the old PlusClient
was, using GoogleApiClient.Builder. Instead of the builder taking the listener objects for the ConnectionCallbacks
and OnConnectionFailedListener
as constructor arguments (which usually lead to this, this, this as arguments), these are now passed in separate methods. Only the context is still passed as a constructor argument, and the others can be omitted if they aren't needed for that particular connection.
A bigger change is that each individual service has to be requested by calling addApi
on the builder. No scopes will be requested by default, so most services will need a call to addScope
as well. Because more than one addScope can be chained, we can avoid worrying about space separating a big string of scopes. Our basic GoogleApiClient
setup to replace a straightforward PlusClient
integration would look like this:
As you might guess, we’ll need to update the types of the connection failed and callbacks interfaces: GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener
. You may have noticed that the onDisconnected callback is now slightly more clearly named as onConnectionSuspended
. Whatever the name, this still indicates the binding to Google Play services is no longer active.
Other than that we call connect
and disconnect
in exactly the same way as before, such as in our onStart/onStop methods:
With the onConnectionFailed
we save and resolve a ConnectionResult
exactly as we would have with PlusClient
. The difference is that once resolved this will connect all client services at once.
Retrieving Friends
The way to work with result sets has changed, as we can see if we look at retrieving the visible collection of friends. The new interface is much more consistently applied across the different APIs, so once you get used to it here you'll find it a familiar pattern with whichever Google service you use next. Rather than all the methods sitting on the client class, they've been divided into logical APIs, such as Plus.PeopleApi
. Each method takes a GoogleApiClient
as the first argument, which is used to execute the call.
The interesting thing is that we have a couple of options on what to do with the PendingResult that comes back. The old PlusClient offered a listener interface which we could implement, and the same thing can be applied with the result here.
However we can also call await
on the response to get the result back in a synchronous fashion. This can be much easier if we know we will hit a point where we cannot continue without the result, and are working off the UI thread. In both cases we can test whether the call was a success by calling the getStatus
method on the result, and then retrieve a buffer for the collection to iterate over as normal. Its important we close the buffer at the end.
Note: you must have enabled the Google+ API in the developer console, or you’re likely to get back a status of Status{statusCode=NETWORK_ERROR, resolution=null}
.
The really cool side effect of the pending result is that we can make the call before the client is connected! If we put the loadVisible
call in the onCreate
and set up a callback, we’ll be pinged back as soon as the user has signed in. Because this and the other feature are part of PendingResult
rather than being dependent on the API, these methods can be applied to almost any call exposed through the new Play services model, whichever product they're for.
App Activities
Reading App Activities is pretty much the same as the People example, so should be an easy port. Writing has become a little bit simpler, but we need to make sure to request the proper types of App Activity when creating the connection to ensure the user grants us permission to write them. The old addActions
method is no more, so the activity type should be passed to the addApi
method as in a second parameter. This will be familiar to anyone that has used GoogleAuthUtil
to request offline access, except with a custom object instead of a Bundle.
The App Activity types are now set as separate strings, rather than one space separated one. We pass the resulting options object as the (optional) second parameter to our addApi
call to the GoogleApiClient.Builder
.
Writing app activities is pretty straightforward, but because a PendingResult
is returned you can get a notification when the write happens with the same kind of callback as before if desired.
Sign out and revoke
You may have noticed that GoogleApiClient
doesn’t have a methods for clearDefaultAccount
, getAccountName
, or revokeAccessAndDisconnect
. These options from PlusClient
are part of the Plus.AccountApi. The value of the consistent approach to responses really shows with something like revoking access - instead of a custom callback type to get a signal once the user is disconnected, it will return a PendingResult
which you can await or setResultCallback
on just as with any other API.
Using the client with multiple APIs
Part of the original motivation for this change was to make it possible to add other APIs into a single GoogleApiClient
connection. There was an example of connecting both Plus and Drive in one call by adding both APIs in the post on the Android developers blog. All that is required is multiple addApi
and addScope
calls for the various scopes and services required.
That’s about it! As more APIs find their way into Google Play services this type of client should make life a lot easier, and much simpler to extend as you want to add more functionality to your integration. If you have any questions on moving over try the Google+ developers community, or Stack Overflow tag.