title: Android Emulator: This app won't run without Google Play services
body: <p>Since Android 4.2.2 it's possible to run Google Services on the Android Emulator. I'm currently making an Android app and made a test project to see if I can get Google+ sign-in and sign-out to work.</p>
  
  <p>I've followed the following tutorial: 
  <a href="http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/">http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/</a></p>
  
  <p>With extra info used from the following tutorials/sites:</p>
  
  <ul>
  <li><a href="https://developers.google.com/+/mobile/android/getting-started">https://developers.google.com/+/mobile/android/getting-started</a></li>
  <li><a href="https://developers.google.com/+/mobile/android/sign-in">https://developers.google.com/+/mobile/android/sign-in</a></li>
  <li><a href="http://developer.android.com/google/play-services/setup.html#Setup">http://developer.android.com/google/play-services/setup.html#Setup</a></li>
  </ul>
  
  <p>This generated the following code:</p>
  
  <p>AndroidManifest.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.testproject_gmaillogin"
      android:versionCode="1"
      android:versionName="1.0" &gt;
  
      &lt;uses-sdk
          android:minSdkVersion="9"
          android:targetSdkVersion="19" /&gt;
  
      &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
      &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;
      &lt;uses-permission android:name="android.permission.USE_CREDENTIALS" /&gt;
  
      &lt;application
          android:allowBackup="true"
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme" &gt;
  
          &lt;meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /&gt;
  
          &lt;activity
              android:name="com.example.testproject_gmaillogin.MainActivity"
              android:label="@string/app_name" &gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
  
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>strings.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;resources&gt;
  
      &lt;string name="app_name"&gt;TestProject_GmailLogin&lt;/string&gt;
      &lt;string name="action_settings"&gt;Settings&lt;/string&gt;
  
      &lt;string name="profile_pic_description"&gt;Google Profile Picture&lt;/string&gt;
      &lt;string name="btn_logout_from_google"&gt;Logout from Google&lt;/string&gt;
      &lt;string name="btn_revoke_access"&gt;Revoke Access&lt;/string&gt;
  
  &lt;/resources&gt;
  </code></pre>
  
  <p>activity_main.xml:</p>
  
  <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      android:padding="16dp"
      tools:context=".MainActivity" &gt;
  
      &lt;LinearLayout
          android:id="@+id/profile_layout"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginBottom="20dp"
          android:orientation="horizontal"
          android:weightSum="3"
          android:visibility="gone"&gt;
  
          &lt;ImageView
              android:id="@+id/img_profile_pic"
              android:contentDescription="@string/profile_pic_description"
              android:layout_width="80dp"
              android:layout_height="wrap_content"
              android:layout_weight="1"/&gt;
  
          &lt;LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginLeft="10dp"
              android:orientation="vertical"
              android:layout_weight="2" &gt;
  
              &lt;TextView
                  android:id="@+id/txt_name"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:padding="5dp"
                  android:textSize="20sp" /&gt;
  
              &lt;TextView
                  android:id="@+id/txt_email"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:padding="5dp"
                  android:textSize="18sp" /&gt;
          &lt;/LinearLayout&gt;
      &lt;/LinearLayout&gt;
  
      &lt;com.google.android.gms.common.SignInButton
          android:id="@+id/btn_sign_in"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginBottom="20dp"/&gt;
  
      &lt;Button
          android:id="@+id/btn_sign_out"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="@string/btn_logout_from_google"
          android:visibility="gone"
          android:layout_marginBottom="10dp"/&gt;
  
      &lt;Button
          android:id="@+id/btn_revoke_access"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="@string/btn_revoke_access"
          android:visibility="gone" /&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>MainActivity.java:</p>
  
  <pre><code>package com.example.testproject_gmaillogin;
  
  import com.google.android.gms.common.ConnectionResult;
  import com.google.android.gms.common.GooglePlayServicesUtil;
  import com.google.android.gms.common.SignInButton;
  import com.google.android.gms.common.api.GoogleApiClient;
  import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
  import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
  import com.google.android.gms.common.api.ResultCallback;
  import com.google.android.gms.common.api.Status;
  import com.google.android.gms.plus.Plus;
  import com.google.android.gms.plus.model.people.Person;
  
  import android.support.v7.app.ActionBarActivity;
  import android.content.Intent;
  import android.content.IntentSender.SendIntentException;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.ImageView;
  import android.widget.LinearLayout;
  import android.widget.TextView;
  import android.widget.Toast;
  
  public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, OnClickListener
  {
      // Logcat tag
      private static final String TAG = "MainActivity";
  
      // Profile pix image size in pixels
      private static final int PROFILE_PIC_SIZE = 400;
  
      // Request code used to invoke sign in user interactions
      private static final int RC_SIGN_IN = 0;
  
      // Client used to interact with Google APIs
      private GoogleApiClient mGoogleApiClient;
  
      // A flag indicating that a PendingIntent is in progress and prevents
      // us from starting further intents
      private boolean mIntentInProgress;
  
      // Track whether the sign-in button has been clicked so that we know to resolve
      // all issues preventing sign-in without waiting
      private boolean mSignInClicked;
  
      // Store the connection result from onConnectionFailed callbacks so that we can
      // resolve them when the user clicks sign-in
      private ConnectionResult mConnectionResult;
  
      // The used UI-elements
      private SignInButton btnSignIn;
      private Button btnSignOut, btnRevokeAccess;
      private ImageView imgProfilePic;
      private TextView txtName, txtEmail;
      private LinearLayout profileLayout;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          // Get the UI-elements
          btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
          btnSignOut = (Button) findViewById(R.id.btn_sign_out);
          btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
          imgProfilePic = (ImageView) findViewById(R.id.img_profile_pic);
          txtName = (TextView) findViewById(R.id.txt_name);
          txtEmail = (TextView) findViewById(R.id.txt_email);
          profileLayout = (LinearLayout) findViewById(R.id.profile_layout);
  
          // Set the Button onClick-listeners
          btnSignIn.setOnClickListener(this);
          btnSignOut.setOnClickListener(this);
          btnRevokeAccess.setOnClickListener(this);
  
          mGoogleApiClient = new GoogleApiClient.Builder(this)
              .addConnectionCallbacks(this)
              .addOnConnectionFailedListener(this)
              .addApi(Plus.API, null)
              .addScope(Plus.SCOPE_PLUS_LOGIN)
              .build();
      }
  
      @Override
      protected void onStart(){
          super.onStart();
          mGoogleApiClient.connect();
      }
  
      @Override
      protected void onStop(){
          super.onStop();
  
          if(mGoogleApiClient.isConnected())
              mGoogleApiClient.disconnect();
      }
  
      @Override
      public void onClick(View view){
          switch(view.getId()){
              case R.id.btn_sign_in:
                  signInWithGPlus();
                  break;
              case R.id.btn_sign_out:
                  signOutFromGPlus();
                  break;
              case R.id.btn_revoke_access:
                  revokeGPlusAccess();
                  break;
          }
      }
  
      @Override
      public void onConnectionFailed(ConnectionResult result) {
          if(!result.hasResolution()){
              GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
              return;
          }
  
          if(!mIntentInProgress){
              // Store the ConnectionResult so that we can use it later when the user clicks 'sign-in'
              mConnectionResult = result;
  
              if(mSignInClicked)
                  // The user has already clicked 'sign-in' so we attempt to resolve all
                  // errors until the user is signed in, or they cancel
                  resolveSignInErrors();
          }
      }
  
      @Override
      protected void onActivityResult(int requestCode, int responseCode, Intent intent){
          if(requestCode == RC_SIGN_IN &amp;&amp; responseCode == RESULT_OK)
              SignInClicked = true;
  
              mIntentInProgress = false;
  
              if(!mGoogleApiClient.isConnecting())
                  mGoogleApiClient.connect();
          }
      }
  
      @Override
      public void onConnected(Bundle connectionHint) {
          mSignInClicked = false;
          Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
  
          // Get all the user's information
          getProfileInformation();
  
          // Update the UI after sign-in
          updateUI(true);
      }
  
      @Override
      public void onConnectionSuspended(int cause){
          mGoogleApiClient.connect();
          updateUI(false);
      }
  
      // Updating the UI, showing/hiding buttons and profile layout
      private void updateUI(boolean isSignedIn){
          if(isSignedIn){
              btnSignIn.setVisibility(View.GONE);
              btnSignOut.setVisibility(View.VISIBLE);
              btnRevokeAccess.setVisibility(View.VISIBLE);
              profileLayout.setVisibility(View.VISIBLE);
          }
          else{
              btnSignIn.setVisibility(View.VISIBLE);
              btnSignOut.setVisibility(View.GONE);
              btnRevokeAccess.setVisibility(View.GONE);
              profileLayout.setVisibility(View.GONE);
          }
      }
  
      // Sign-in into Google
      private void signInWithGPlus(){
          if(!mGoogleApiClient.isConnecting()){
              mSignInClicked = true;
              resolveSignInErrors();
          }
      }
  
      // Method to resolve any sign-in errors
      private void resolveSignInErrors(){
          if(mConnectionResult.hasResolution()){
              try{
                  mIntentInProgress = true;
  
                  //Toast.makeText(this, "Resolving Sign-in Errors", Toast.LENGTH_SHORT).show();
  
                  mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
              }
              catch(SendIntentException e){
                  // The intent was cancelled before it was sent. Return to the default
                  // state and attempt to connect to get an updated ConnectionResult
                  mIntentInProgress = false;
                  mGoogleApiClient.connect();
              }
          }
      }
  
      // Fetching the user's infromation name, email, profile pic
      private void getProfileInformation(){
          try{
              if(Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null){
                  Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
                  String personName = currentPerson.getDisplayName();
                  String personPhotoUrl = currentPerson.getImage().getUrl();
                  String personGooglePlusProfile = currentPerson.getUrl();
                  String personEmail = Plus.AccountApi.getAccountName(mGoogleApiClient);
  
                  Log.e(TAG, "Name: " + personName + ", "
                          + "plusProfile: " + personGooglePlusProfile + ", "
                          + "email: " + personEmail + ", "
                          + "image: " + personPhotoUrl);
  
                  txtName.setText(personName);
                  txtEmail.setText(personEmail);
  
                  // by default the profile url gives 50x50 px image,
                  // but we can replace the value with whatever dimension we
                  // want by replacing sz=X
                  personPhotoUrl = personPhotoUrl.substring(0, personPhotoUrl.length() - 2)
                          + PROFILE_PIC_SIZE;
  
                  new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
              }
              else{
                  Toast.makeText(getApplicationContext(), "Person information is null", Toast.LENGTH_LONG).show();
              }
          }
          catch(Exception ex){
              ex.printStackTrace();
          }
      }
  
      // Sign-out from Google
      private void signOutFromGPlus(){
          if(mGoogleApiClient.isConnected()){
              Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
              mGoogleApiClient.disconnect();
              mGoogleApiClient.connect();
              updateUI(false);
          }
      }
  
      // Revoking access from Google
      private void revokeGPlusAccess(){
          if(mGoogleApiClient.isConnected()){
              Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
              Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
                  .setResultCallback(new ResultCallback&lt;Status&gt;(){
                      @Override
                      public void onResult(Status s){
                          Log.e(TAG, "User access revoked!");
                          mGoogleApiClient.connect();
                          updateUI(false);
                      }
                  });
          }
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          int id = item.getItemId();
          if (id == R.id.action_settings)
              return true;
  
          return super.onOptionsItemSelected(item);
      }
  }
  </code></pre>
  
  <p>LoadProfileImage.java:</p>
  
  <pre><code>package com.example.testproject_gmaillogin;
  
  import java.io.InputStream;
  
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.os.AsyncTask;
  import android.util.Log;
  import android.widget.ImageView;
  
  /**
   * Background async task to load user profile picture from url
   **/
  public class LoadProfileImage extends AsyncTask&lt;String, Void, Bitmap&gt; {
      private ImageView bmImage;
  
      public LoadProfileImage(ImageView bmImage){
          this.bmImage = bmImage;
      }
  
      @Override
      protected Bitmap doInBackground(String... urls){
          String urlDisplay = urls[0];
          Bitmap mIcon11 = null;
          try{
              InputStream in = new java.net.URL(urlDisplay).openStream();
              mIcon11 = BitmapFactory.decodeStream(in);
          }
          catch(Exception ex){
              Log.e("Error", ex.getMessage());
              ex.printStackTrace();
          }
          return mIcon11;
      }
  
      @Override
      protected void onPostExecute(Bitmap result){
          bmImage.setImageBitmap(result);
      }
  }
  </code></pre>
  
  <p>The other steps I did were:</p>
  
  <p>At <a href="https://console.developers.google.com/project">https://console.developers.google.com/project</a> I've created a project with:</p>
  
  <p>Google+ API on:</p>
  
  <p><img src="https://i.stack.imgur.com/MIenh.png" alt="Google+ API on"></p>
  
  <p>And a Client ID created with the correct SHA1 and exact same namespace as the project:</p>
  
  <p><img src="https://i.stack.imgur.com/LwXdx.png" alt="And a Client ID created with the correct SHA1"></p>
  
  <p>At Eclipse:</p>
  
  <p>I've installed the google-play-services library:</p>
  
  <p><img src="https://i.stack.imgur.com/UGa2d.png" alt="Google-play services installed"></p>
  
  <p>And added it to the project:</p>
  
  <p><img src="https://i.stack.imgur.com/z4ybG.png" alt="Google-play services library added (2)">
  <img src="https://i.stack.imgur.com/cK9HV.png" alt="Google-play services library added (2)"></p>
  
  <p>I've also created an Emulator with version 4.4.2:</p>
  
  <p><img src="https://i.stack.imgur.com/Vkvnk.png" alt="I&#39;ve also created an Emulator with version 4.4.2"></p>
  
  <p>But when I run the app I get the following error, and this error keeps popping up when I click on the button:</p>
  
  <p><img src="https://i.stack.imgur.com/HMtJG.png" alt="Get Google Play services Error"></p>
  
  <p>Anyone has any idea where it goes wrong? Thanks in advance for the responses.</p>