Mobile
Article

Authentication and Sharing in Android with the Google+ API

By Theodhor Pandeli

In this tutorial I will show how to connect your Android application to the Google Plus API and use it for login, getting and sharing data.

Find the completed project on GitHub.

Create Android Project

Open Android Studio and create a New Project, naming it as you wish. Click Next, choose Minimum API level 18 and click Next again. Choose Blank Activity as the first activity, name it LoginActivity and click Finish.

Setting up Gradle

Open build.gradle (Module) and add apply plugin: 'com.google.gms.google-services' to the top of the file. Add these lines after testCompile 'junit:junit:4.12':

androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'
androidTestCompile 'com.android.support:support-annotations:23.1.1'
compile 'com.google.android.gms:play-services-auth:8.3.0'
compile 'com.google.android.gms:play-services-identity:8.3.0'
compile 'com.google.android.gms:play-services:8.3.0'

Now open build.gradle (Project) and add this line inside dependencies :

classpath 'com.google.gms:google-services:1.5.0-beta2'

The next step is adding the file google-services.json to your project. This file contains developer credentials and configuration settings to connect to the Google Api Client. You can download this file here, move it inside the app folder of your project and Sync gradle.

Layouts

In the layout folder of your project, delete the content_login.xml file.

Inside activity_login.xml, delete the <include layout="@layout/content_login"/> and replace the Floating Action Button code with these lines. The only thing we need in this layout is the Login Button:

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_weight="1">

    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:visibility="visible"
        tools:visibility="gone" />

    <LinearLayout
        android:id="@+id/sign_out_and_disconnect"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:visibility="gone"
        tools:visibility="visible">

        <Button
            android:id="@+id/sign_out_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Sign Out"  />

    </LinearLayout>

</RelativeLayout>

Open the LoginActivity class and delete the Floating Action Button code inside the onCreate() method.

Make sure your public class LoginActivity extends AppCompatActivity and implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener{

Before the onCreate() method add this code:

private static final String TAG = "LoginActivity";
private static final int SIGN_IN_CODE = 9001;
private GoogleApiClient mGoogleApiClient;
private ProgressDialog mProgressDialog;
private GoogleSignInAccount account;

Inside the onCreate method, before the closing bracket, add these lines which set-up connections to the Google API and bind them to a sign-in button:

findViewById(R.id.sign_in_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestEmail()
        .build();

mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this , this)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .build();

SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_STANDARD);
signInButton.setScopes(gso.getScopeArray());

After the onCreate() method we are going to implement overridden methods. The first is onStart() and a placeholder for the onConnectionFailed method. Add them inside the LoginActivity class:

@Override
public void onStart() {
    super.onStart();
    OptionalPendingResult<GoogleSignInResult> optPenRes = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
    if (optPenRes.isDone()) {
        Log.d(TAG, "Yayy!");
        GoogleSignInResult result = optPenRes.get();
        handleSignInResult(result);
    } else {
        optPenRes.setResultCallback(new ResultCallback<GoogleSignInResult>() {
            @Override
            public void onResult(GoogleSignInResult googleSignInResult) {
                handleSignInResult(googleSignInResult);
            }
        });
    }
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}

Do not worry about the errors you will likely see, as we are going to implement these methods later.

The second overridden method is onActivityResult(). Add it after the last method added. The code is as follows:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == SIGN_IN_CODE) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    }
}

Next add the handeSignInResult() method after the onActivityResult() method:

private void handleSignInResult(GoogleSignInResult result) {
  Log.d(TAG, "handleSignInResult:" + result.isSuccess());
  if (result.isSuccess()) {
      updateUI(true);
      account = result.getSignInAccount();
  } else {
      updateUI(false);
  }
}

Now we will add the signIn() and signOut() methods:

private void signIn() {
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, SIGN_IN_CODE);
}

private void signOut() {
    Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    updateUI(false);
                }
            });
}

The next method is updateUI(). If the user is signed in, then it changes the visibility of the sign in and sign out buttons, and creates a new Intent called main which represents the next activity opened after we have a successful sign in process. The next activity is MainActivity. Before we switch activities, we should pass some extra data received as account information. We are passing the displayname and imageurl strings to the new intent as extras.

private void updateUI(boolean signedIn) {
    if (signedIn) {
        findViewById(R.id.sign_in_button).setVisibility(View.GONE);
        findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE);
        Intent main = new Intent(this, MainActivity.class);
        main.putExtra("displayname", account.getDisplayName());
        main.putExtra("imageurl", account.getPhotoUrl().toString());
        startActivity(main);
        finish();
    } else {
        findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
        findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE);
    }
}

The last method we need to implement in our LoginActivity class is onClick(View v):

@Override
public void onClick(View v) {
  switch (v.getId()) {
      case R.id.sign_in_button:
          signIn();
          break;
      case R.id.sign_out_button:
          signOut();
          break;
  }
}

The LoginActivity class is now complete.

Main Activity Class

We need another class to display user information and profile picture and to place a Google Plus Share button. Start with creating a new class by right-clicking on your package (e.g: com.example.theodhor.googleplusintegration) and selecting to New -> Activity -> Blank Activity. Leave the default name of MainActivity and click Finish.

Delete the content_main.xml file because we don’t need it.

Open activity_main.xml and replace <include layout="@layout/content_main"/> with:

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:paddingTop="100dp">

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello"
      android:id="@+id/textView"
      android:layout_gravity="center_horizontal"/>

  <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="New Text"
      android:id="@+id/nameSurnameText"
      android:layout_gravity="center_horizontal"/>

  <ImageView
      android:layout_width="150dp"
      android:layout_height="150dp"
      android:id="@+id/imageView"
      android:layout_gravity="center_horizontal"/>

  <Button
      android:id="@+id/share_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Share on Google+"
      android:layout_gravity="center_horizontal"/>

  <Button
      android:id="@+id/sign_out_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Sign Out"
      android:visibility="visible"
      android:layout_gravity="center"/>

</LinearLayout>

Delete the Floating Action Button code as we won’t use it.

Now open the MainActivity class and we’ll add the code to make it work.

Firstly make sure the class extends and implements classes we will use:

public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

Before the onCreate() method add these two lines of code:

GoogleApiClient mGoogleApiClient;
private static final int SIGN_IN_CODE = 9001;

Inside the onCreate() method, replace the Floating Action Button code with these lines:

findViewById(R.id.sign_out_button).setOnClickListener(this);

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
  .requestEmail()
  .build();

mGoogleApiClient = new GoogleApiClient.Builder(this)
  .enableAutoManage(this , this)
  .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
  .build();

Here we created the sign out button and built a new GoogleApiClient that will set which API we’re going to use for our application. In this case we will use Google Authentication since we are performing a Google Plus Login.

Inside the same method, add these lines:

Intent intent = getIntent();
  String nameSurname = intent.getStringExtra("displayname");
  String imageUrl = intent.getStringExtra("imageurl");
  TextView displayName = (TextView)findViewById(R.id.nameSurnameText);
  displayName.setText("" + nameSurname);

Here we create an intent and use it to get the extras sent form the last activity, the of displayname and imageurl strings.

Next we should add the code that creates the share button:

Button shareButton = (Button) findViewById(R.id.share_button);
shareButton.setOnClickListener(this);

Since View.OnClickListener is implemented in this class, we need the overridden method for it. Add it after the onCreate() method:

@Override
public void onClick(View v) {
  switch (v.getId()) {
      case R.id.sign_in_button:
          signIn();
          break;
      case R.id.sign_out_button:
          signOut();
          break;
      case R.id.share_button:
          Intent shareIntent = new PlusShare.Builder(this)
                  .setType("text/plain")
                  .getIntent();
          startActivityForResult(shareIntent, 0);
          break;
  }
}

The remaining methods for this class are signIn() , signOut() and an overridden method called onConnectionFailed() :

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}

private void signOut() {
  Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
          new ResultCallback<Status>() {
              @Override
              public void onResult(Status status) {
                  Intent login = new Intent(MainActivity.this, LoginActivity.class);
                  startActivity(login);
                  finish();
              }
          });
}

private void signIn() {
  Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
  startActivityForResult(signInIntent, SIGN_IN_CODE);
}

From LoginActivity we receive the displayname and imageurl as strings. The first will be displayed as text using a TextView but the seconds needs to be displayed as an image. Let’s create another class that uses our imageurl string to download and show a bitmap image.

Create a new class by right-clicking your package and selecting New -> Java Class. I called it DownloadImageTask and it’s code is below:

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
  ImageView bmImage;

  public DownloadImageTask(ImageView mImage) {
      this.bmImage = mImage;
  }

  protected Bitmap doInBackground(String... urls) {
      String url = urls[0];
      Bitmap mBitmap = null;
      try {
          InputStream in = new java.net.URL(url).openStream();
          mBitmap = BitmapFactory.decodeStream(in);
      } catch (Exception e) {
          Log.e("Error", e.getMessage());
          e.printStackTrace();
      }
      return mBitmap;
  }

  protected void onPostExecute(Bitmap result) {
      bmImage.setImageBitmap(result);
  }
}

To call it in our MainActivity class add this line of code inside the onCreate() method:

new DownloadImageTask((ImageView) findViewById(R.id.imageView)).execute(imageUrl);

Enabling Google Play Services

The last task is connecting our application to Google APIs. Click here to browse the Google Services Page.

Add your application name and package name and click Continue.

On the next view add your SHA-1 fingerprint key. If you don’t know how to do this, Google’s help pages are the best source of information.

Click Continue to generate the configuration files we need, download the google-services.json file and move it inside your YourProjectName/app/ or mobile/ directory.

Now you can run the application.

Final Application

Conclusion

In this tutorial I showed some basic steps to integrate Google Plus into an Android application for authentication and sharing content. There is much more that can be accomplished with this integration such as social graph information, deep linking and over air installs.

I’d love to hear any questions, issues and ideas you may have.

  • Jackson Welch

    I followed this exactly and it still didn’t work. Any thoughts??

    • Theodhor Pandeli

      Hi Jackson, I just reviewed the code and it is okay, but can you tell me, does it crash or gives errors in Error Log?

      • Jackson Welch

        it just doesn’t sign in. it prompts me with the prompt to sign in however after that it just goes away. when I hit it again the screen gets darker for about two seconds, then nothing. I have created a .JSON file and it is in my project.

  • Alice John

    I am getting the error that PlusShare cannot be resolved…Plz Help

    • Theodhor Pandeli

      Hi Alice, are your imports all right? Please check if you have imported the following inside the MainActivity:

      import com.google.android.gms.plus.PlusShare;
      import com.google.android.gms.plus.PlusShare.Builder;
      import com.google.android.gms.plus.internal.model.people.PersonEntity;

      Please tell me if you still have problems :)

  • Pooja Mehta

    Hi! This code works fine for me when I am running the application directly from Android Studio in developer mode but since I need to integrate Google Sign-In for my final year project which I need to upload on the play store, the signed apk doesn’t let me sign-in into my account. The isSuccess()

    method of GoogleSignInResult instance returns false and hence I am not able to log in to my application. Please guide me in whichever way you can! Thanks!

    • Theodhor Pandeli

      Hello, since it returns false I think the code is okay, just make sure that you are using the right API keys. The key hash you used before is for the debug type of the app. So to generate the Key Hash you need, you should use the release key.

      Hope it works!

      • Pooja Mehta

        Hello, I have even tried this solution before but unfortunately the signed apk still doesn’t work. It still returns false.

        • Theodhor Pandeli

          It seems hard to tell what is the problem. Does it show any error in the log?
          And something else, is the “google-services.json” file inside the project?

          • Pooja Mehta

            Hello, I am already kept the google-services.json file inside the project and I am not getting any errors as such specifically but I just cant log into the account. This problem is only happening for lollipop and marshmallow devices. I surfed a lot for this issue but I am not able to get any solution for it. Thanks!

  • Daenys PiedradelValle

    Hi, I’m getting the same scene. I download the project from GitHub and run it on my device. I get a screen with the login button and when I click on it, the screen gets darker for two seconds and then nothing happens. I don’t know how to put he SHA1 key on the project or how can I “Enable Google Sign-In”
    Please help! :)

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Mobile, once a week, for free.