Google Plus Services, Login and +1 in Xamarin.Android
I have been dabbling around recently with integrating Google Play Services into Android applications. Play Services are pretty interesting as they offer up a nice set of functionality including a G+ Sign In button and +1 sharing on G+. This is pretty intriguing to me because I have been building out a podcast streaming app for the Dot Net Rocks show. I wanted to build out a small sample to test what the details page might look like allowing my users to +1 and share a link. I also wanted to see what information I could get on the user when they logged in and create a small profile page. So here is how to get started:
Add the Component:
UPDATE V13 is now available in the component store, so no need to download the old version. Get the new component here.
Currently on the Xamarin component store there is a binding for Play Services v12 (and a blog post about it) that you can add to your Xamarin.Android project. This is great as they have done all of the hard work for you, but technically Play Services are on v13, so you will actually have to download the older Play Service v12 manually as instructed here (the android sdk should be installed in: /Users/<UserName>/Library/Developer/Xamarin/android sdk). After this has been added there is one important thing to do which is to increase your Heap size of your app as the Play Service binding is large. You can do this under your project properties -> Android Build -> Advanced -> Java Heap Size. Then everything will build!
Settings up Google App & API:
The next part is bit in depth as you will need to setup a google app and the API that the google play services will talk to. Google has a pretty great guide, but here are the pointers: *Note I am doing this on Mac OSX 10.9, on Windows the locations will differ.
- Create new app at Google App Console
- Go to Services and enable Google+ API
For this next part I switched back to the old console - Get the SHA1 for your keystore (I am using debug to test, but you will want to use a final release keystore that you have to create before you ship).
- Find your debug.keystore in: /Users/<UserName>/.local/share/Xamarin/Mono for Android/debug.keystore
- Copy it into Java in /Library/Java/Home/bin
- Run this command in terminal after navigating to that directory:
keytool -exportcert -alias androiddebugkey -keystore <path-to-debug-or-production-keystore> -list -v
- This will output your SHA1 you will need:
- Use this to add oAuth to your app!
Alright let’s integrate this puppy into our app! First thing I want to layout is a sign in button, +1 button, log out button, and then a small details section. Here is what my axml is looking like at this point:
Sign In and Out:
Next we need to add some backend code. You will need to add the following permissions for Google Plus Login to work: Internet, Get Accounts, and Use Credentials. The first thing to do is to create our GooglePlusClient and grab our LoginButton and PlusOneButton:
In AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
plusClient = new PlusClient.Builder(this, this, this).Build();
googleLoginButton = FindViewById<SignInButton>(Resource.Id.sign_in_button);
plusOneButton = FindViewById<PlusOneButton>(Resource.Id.plus_one_button);
Let’s first implement our login button. I have created a helper method to handle the connection that I am calling ResolveLogin and when I get a connection it triggers an OnActivityResult:
private void ResolveLogin(ConnectionResult result)
{
if (result.HasResolution)
{
try
{
result.StartResolutionForResult (this, 9000);
}
catch (Android.Content.IntentSender.SendIntentException e)
{
plusClient.Connect ();
}
}
else if(progressDialog != null && progressDialog.IsShowing)
{
progressDialog.Dismiss ();
}
}
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult (requestCode, resultCode, data);
if (requestCode != 9000)
return;
if (resultCode == Result.Ok)
plusClient.Connect ();
else
progressDialog.Dismiss ();
}
}
Then we will need to implement 2 different interfaces IGooglePlayServicesClientConnectionCallbacks, IGooglePlayServicesClientOnConnectionFailedListener. In addition I will also try to connect on start of the activity and stop on end of activity.
public void OnConnected (Bundle p0)
{
progressDialog.Dismiss ();
RefreshPlusOneButton ();
UpdateProfile ();
Toast.MakeText (this, "Connected!", ToastLength.Long).Show ();
}
public void OnDisconnected ()
{
Toast.MakeText (this, "Disconnected!", ToastLength.Long).Show ();
}
public void OnConnectionFailed (ConnectionResult result)
{
if (progressDialog.IsShowing)
ResolveLogin (result);
connectionResult = result;
Toast.MakeText (this, "Connection Failed!", ToastLength.Long).Show ();
}
In our OnCreate we will also now want to register for these callbacks:
plusClient.RegisterConnectionCallbacks (this);
plusClient.IsConnectionFailedListenerRegistered (this);
To handle the click event of the Sign in button, we simply have to check to see if we are logged in and if not try to sign. Google handle the rest:
googleLoginButton.Click += (sender, e) =>
{
if(plusClient.IsConnected || plusClient.IsConnecting)
return;
progressDialog.Show();
if (connectionResult == null)
plusClient.Connect();
else
ResolveLogin(connectionResult);
};
Once we are connected we can pull in the connected user’s data:
private void UpdateProfile()
{
profileTextView.Text = plusClient.CurrentPerson.DisplayName;
nickNameTextView.Text = plusClient.CurrentPerson.Nickname;
aboutTextView.Text = plusClient.CurrentPerson.AboutMe;
imageLoader.DisplayImage (plusClient.CurrentPerson.Image.Url, imageView, Resource.Drawable.default_icon);
}
If the user wants to log out we just have to revoke permission on the PlusClient and implement the IOnAccessRevokedListener interface:
logoutButton.Click += (sender, e) =>
{
if(!plusClient.IsConnected || plusClient.IsConnecting)
return;
plusClient.RevokeAccessAndDisconnect(this);
};
+1 Button:
Adding the +1 is extremely simple after you have finished implementing the login button. When you call Initialize on the button you can pass it the URL and the PlusClient and it will handle the rest. I simply put this in a helper method so I can call it when the activity Resumes, Connects, Disconnects, or access is revoked:
private void RefreshPlusOneButton ()
{
plusOneButton.Initialize ("http://blog.xamarin.com/microsoft-and-xamarin-partner-globally/", 0);
}
There you have it, implementing Google Plus Sign In and a +1 button! I have the full source code on GitHub!