Использование учетной записи Google для входа в приложение Android

Я разрабатываю приложение для Android и хочу, чтобы пользователи могли входить в систему со своей учетной записью Google. Как я могу этого добиться?


person Androbito    schedule 01.04.2012    source источник


Ответы (7)


Возможно, вы захотите аутентифицировать пользователя, используя одну из учетных записей Google, уже настроенных на вашем устройстве, как это делают некоторые из приложений, для этого перейдите по ссылке ниже -

«Аутентификация в службах OAuth2» - http://developer.android.com/training/id-auth/authenticate.html

Загрузить образец из Google - Android SDK Manager / Extras / Google Play Services

Простыми шагами это делает

  1. Показывает список учетных записей в вашем мобильном телефоне
  2. Создает токен доступа из выбранных учетных записей
  3. Получает имя учетной записи из токена доступа, связавшись со службами Google (отдельный вызов), чтобы просто сообщить, что он прошел аутентификацию.

Это еще одна ссылка, которая хорошо объясняет процесс - http://android-developers.blogspot.in/2013/01/verifying-back-end-calls-from-android.html

вы можете выполнить следующие шаги для входа в свое приложение

  1. вы отправите сгенерированный токен доступа на свой Back-end сервер
  2. Внутренний сервер проверяет, действителен ли токен доступа, связываясь со службами Google по этому URL "https://www.googleapis.com/oauth2/v1/userinfo?access_token=ACCESS_TOKEN "
  3. Далее Внутренний сервер отвечает приложению, следует ли пользователю войти в систему или нет.

Ниже приведен формат ответа на указанный выше вызов "userinfo".

{
 "id": "ID",
 "name": "NAME",
 "given_name": "GiVEN NAME",
 "family_name": "FAMILY_NAME",
 "link": "https://plus.google.com/ID",
 "picture": "https://PHOTO.jpg",
 "gender": "GENDER",
 "locale": "LOCALE"
}

Если вам нужен идентификатор электронной почты вместе с этим ответом, вам необходимо изменить

SCOPE = "oauth2: https://www.googleapis.com/auth/userinfo.profile ";

to

SCOPE = "oauth2: https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email ";

в этом образце

person Balaji    schedule 08.03.2013
comment
Я попытался получить значение given_name, family_name, как описано в вашем ответе, но получил только ответ ниже {id: 105024889100906846764, email: [email protected], Verified_email: true, locale: en} - person Herry; 26.07.2013
comment
@Herry, понятия не имею, почему он не возвращает вам given_name и family_name, но я уверен, что получил эти данные при запуске образца из Google, лучше попробуйте с другим адресом электронной почты. - person Balaji; 29.07.2013
comment
Спасибо, это очень помогло мне. - person Mahmudur Rahman; 21.07.2016

Сначала вставьте следующую строку в свои зависимости build.gradle

compile 'com.google.android.gms:play-services:7.5.0'

Теперь нам нужен отпечаток SHA-1, который мы должны предоставить в Google Developers Console.

Java keytool используется для генерации отпечатка SHA-1. Откройте командную строку [Откройте C: \ Program Files \ Java \ jdk \ bin, затем нажмите Shift + правый щелчок] и выполните следующую команду, чтобы сгенерировать отпечаток SHA-1, а для пароля введите android, если будет предложено.

keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

Для аутентификации и взаимодействия с API Google+ необходимо создать проект Google Developers Console, в котором необходимо включить API Google+ и создать идентификатор клиента OAuth 2.0.

  1. Перейдите к консоли разработчика Google. и создать новый проект
  2. Когда вы закончите создание проекта, нажмите API в разделе API и аутентификации. Найдите API Google+ и выберите тот, который я показал на изображении ниже.
  3. Включите Google+ API, нажав кнопку «Включить API».
  4. После включения перейдите в раздел «Учетные данные» в API и создайте новый идентификатор клиента.
  5. Выберите установленное приложение в качестве типа и настройте экран согласия.
  6. Теперь введите имя пакета вашего проекта, вставьте отпечаток пальца SHA1, включите опцию Deep Linking, чтобы активировать интерактивные сообщения и все другие параметры, как показано на изображении ниже.

Пришло время объявить разрешения для вашего файла mainfest. Вот как будет выглядеть ваш файл манифеста после добавления метаданных и всех разрешений.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androstock.loginwithgoogle" >

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

Теперь мы направляемся к нашему классу MainActivity.java, где мы будем делать все, что нам нужно для входа в Google+.

package com.androstock.loginwithgoogle;

import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
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;

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.OnConnectionFailedListener;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;

import java.io.InputStream;


// A project by Ferdousur Rahman Shajib
// www.androstock.com

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

    // Profile pic 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;

private boolean mShouldResolve;

private ConnectionResult connectionResult;

private SignInButton signInButton;
private Button signOutButton;
private TextView tvName, tvMail, tvNotSignedIn;
private ImageView imgProfilePic;
private LinearLayout viewContainer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
    signInButton = (SignInButton) findViewById(R.id.sign_in_button);
    signOutButton = (Button) findViewById(R.id.sign_out_button);
    tvName = (TextView) findViewById(R.id.tvName);
    tvMail = (TextView) findViewById(R.id.tvMail);
    tvNotSignedIn = (TextView) findViewById(R.id.notSignedIn_tv);
    viewContainer = (LinearLayout) findViewById(R.id.text_view_container);



    signInButton.setOnClickListener(this);
    signOutButton.setOnClickListener(this);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(Plus.API)
            .addScope(Plus.SCOPE_PLUS_LOGIN)
            .build();

}

protected void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

protected void onStop() {
    super.onStop();
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}


private void resolveSignInError() {
    if (connectionResult.hasResolution()) {
        try {
            mIntentInProgress = true;
            connectionResult.startResolutionForResult(this, RC_SIGN_IN);
        } catch (SendIntentException e) {
            mIntentInProgress = false;
            mGoogleApiClient.connect();
        }
    }
}

/*
When the GoogleApiClient object is unable to establish a connection onConnectionFailed() is called
 */
@Override
public void onConnectionFailed(ConnectionResult result) {
    if (!result.hasResolution()) {
        GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
                0).show();
        return;
    }

    if (!mIntentInProgress) {

        connectionResult = result;

        if (mShouldResolve) {

            resolveSignInError();
        }
    }

}

/*
onConnectionFailed() was started with startIntentSenderForResult and the code RC_SIGN_IN,
we can capture the result inside Activity.onActivityResult.
 */
@Override
protected void onActivityResult(int requestCode, int responseCode,
                                Intent intent) {
    if (requestCode == RC_SIGN_IN) {
        if (responseCode != RESULT_OK) {
            mShouldResolve = false;
        }

        mIntentInProgress = false;

        if (!mGoogleApiClient.isConnecting()) {
            mGoogleApiClient.connect();
        }
    }
}

@Override
public void onConnected(Bundle arg0) {
    mShouldResolve = false;
    try {
        if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
            Person person = Plus.PeopleApi
                    .getCurrentPerson(mGoogleApiClient);
            String personName = person.getDisplayName();
            String personPhotoUrl = person.getImage().getUrl();
            String email = Plus.AccountApi.getAccountName(mGoogleApiClient);

            tvName.setText(personName);
            tvMail.setText(email);

            personPhotoUrl = personPhotoUrl.substring(0,
                    personPhotoUrl.length() - 2)
                    + PROFILE_PIC_SIZE;

            new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);

            Toast.makeText(getApplicationContext(),
                    "You are Logged In " + personName,             Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(),
                    "Couldnt Get the Person Info", Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    signOutUI();

}

private void signOutUI() {
    signInButton.setVisibility(View.GONE);
    tvNotSignedIn.setVisibility(View.GONE);
    signOutButton.setVisibility(View.VISIBLE);
    viewContainer.setVisibility(View.VISIBLE);
}

private void signInUI() {
    signInButton.setVisibility(View.VISIBLE);
    tvNotSignedIn.setVisibility(View.VISIBLE);
    signOutButton.setVisibility(View.GONE);
    viewContainer.setVisibility(View.GONE);
}

/**
 * Fetching user's information name, email, profile pic
 */
private void getProfileInformation() {

}

@Override
public void onConnectionSuspended(int arg0) {
    mGoogleApiClient.connect();
    signInUI();
}



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


private void onSignInClicked() {
    if (!mGoogleApiClient.isConnecting()) {
        mShouldResolve = true;
        resolveSignInError();
    }
}


private void onSignOutClicked() {
    if (mGoogleApiClient.isConnected()) {
        Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
        mGoogleApiClient.disconnect();
        signInUI();
    }
}





/**
 * Background Async task to load user profile picture from url
 * */
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public LoadProfileImage(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    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 e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

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



}

Создайте файл activity_main.xml, который будет содержать наш макет входа и выхода.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">

<LinearLayout
    android:id="@+id/text_view_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:visibility="gone"
    android:gravity="center">

    <ImageView
        android:id="@+id/imgProfilePic"
        android:layout_width="80dp"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/tvMail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textSize="18dp" />

</LinearLayout>

<Button
    android:id="@+id/sign_out_button"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:background="@android:color/holo_red_light"
    android:layout_marginLeft="19dp"
    android:layout_marginRight="19dp"
    android:text="LOGOUT"
    android:textColor="#fff"
    android:textStyle="bold"
    android:visibility="gone" />

<TextView
    android:id="@+id/notSignedIn_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginBottom="30dp"
    android:text="You are not Signed In"
    android:textSize="20sp" />

<com.google.android.gms.common.SignInButton
    android:id="@+id/sign_in_button"
    android:layout_width="220dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" />

</LinearLayout>

Вот и все, ребята. Вы закончили с входом в Google+. Для получения дополнительных сведений посетите здесь < / а>.

person Ferdousur Rahman Shajib    schedule 05.11.2015
comment
Я получаю сообщение об ошибке: java.lang.NullPointerException: не запрашивался соответствующий API. при намерении signInIntent = Auth.GoogleSignInApi.getSignInIntent (mGoogleApiClient); - person Miguel Silva; 24.02.2021

Взгляните на http://developer.android.com/training/id-auth/index.html Здесь вы найдете руководство по использованию Менеджера учетных записей. (Более конкретно, http://developer.android.com/reference/android/accounts/AccountManager.html)

person fwal    schedule 20.04.2012

Вот как я интегрирую вход в Google с помощью новейшего и самого удобного способа.

Из этой ссылки: google login android studio

сначала создайте приложение в консоли разработчика Google, загрузите файл конфигурации и скопируйте его в папку приложения.

затем добавьте следующее в build.gradle(Project: project_name)

classpath 'com.google.gms:google-services:1.5.0-beta2'
 maven { url 'https://jitpack.io' }
allprojects {
    repositories {
 }
}

добавить код в build.gradle(Module:app)

compile 'com.google.android.gms:play-services-auth:9.0.2'
    compile 'com.google.android.gms:play-services:9.0.2'
    compile 'com.github.androidquery:androidquery:0.26.9'

добавить следующее в activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context="com.exampledemo.parsaniahardik.google_login_demonuts.MainActivity">

    <ImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="fitXY"
        android:layout_marginTop="20dp"
        android:layout_gravity="center_horizontal"
        android:id="@+id/iv"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:textColor="#000"
        android:layout_marginTop="20dp"
        android:textAppearance="?android:attr/textAppearanceMedium"/>

    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="200dp"
        android:layout_marginTop="20dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />
    <Button
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_gravity="center_horizontal"
        android:text="Logout"
        android:id="@+id/btn"/>
</LinearLayout>

добавьте ниже в MainActivity.java

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.androidquery.AQuery;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.People;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;

public class MainActivity extends AppCompatActivity implements  GoogleApiClient.OnConnectionFailedListener{

    private SignInButton signInButton;
    private GoogleSignInOptions gso;
    private GoogleApiClient mGoogleApiClient;
    private int SIGN_IN = 30;
    private TextView tv;
    private ImageView iv;
    private AQuery aQuery;
    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        signInButton = (SignInButton) findViewById(R.id.sign_in_button);
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .addApi(Plus.API)
                .build();

        signInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                startActivityForResult(signInIntent, SIGN_IN);
            }
        });

        tv = (TextView) findViewById(R.id.text);
        iv = (ImageView) findViewById(R.id.iv);
        btn = (Button) findViewById(R.id.btn);
        aQuery = new AQuery(this);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                        new ResultCallback<Status>() {
                            @Override
                            public void onResult(Status status) {
                                Toast.makeText(MainActivity.this, "Logout Successfully!", Toast.LENGTH_SHORT).show();
                            }
                        });
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //If signin
        if (requestCode == SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            //Calling a new function to handle signin
            handleSignInResult(result);
        }
    }

    private void handleSignInResult(GoogleSignInResult result) {
        //If the login succeed
        if (result.isSuccess()) {
            //Getting google account
            final GoogleSignInAccount acct = result.getSignInAccount();

            //Displaying name and email
            String name = acct.getDisplayName();
            final String mail = acct.getEmail();
            // String photourl = acct.getPhotoUrl().toString();

            final String givenname="",familyname="",displayname="",birthday="";

            Plus.PeopleApi.load(mGoogleApiClient, acct.getId()).setResultCallback(new ResultCallback<People.LoadPeopleResult>() {
                @Override
                public void onResult(@NonNull People.LoadPeopleResult loadPeopleResult) {
                    Person person = loadPeopleResult.getPersonBuffer().get(0);

                    Log.d("GivenName ", person.getName().getGivenName());
                    Log.d("FamilyName ",person.getName().getFamilyName());
                    Log.d("DisplayName ",person.getDisplayName());
                    Log.d("gender ", String.valueOf(person.getGender())); //0 = male 1 = female
                    String gender="";
                    if(person.getGender() == 0){
                        gender = "Male";
                    }else {
                        gender = "Female";
                    }

                    if(person.hasBirthday()){
                        tv.setText(person.getName().getGivenName()+" \n"+person.getName().getFamilyName()+" \n"+gender+"\n"+person.getBirthday());
                    }else {
                        tv.setText(person.getName().getGivenName()+" \n"+person.getName().getFamilyName()+" \n"+gender);

                    }
                    aQuery.id(iv).image(acct.getPhotoUrl().toString());
                   Log.d("Uriddd",acct.getPhotoUrl().toString());
                  /*   Log.d(TAG,"CurrentLocation "+person.getCurrentLocation());
                    Log.d(TAG,"AboutMe "+person.getAboutMe());*/
                    // Log.d("Birthday ",person.getBirthday());
                    // Log.d(TAG,"Image "+person.getImage());
                }
            });
        } else {
            //If login fails
            Toast.makeText(this, "Login Failed", Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}
person Parsania Hardik    schedule 04.03.2017

Конечно, вы можете начать с этого:

Сторонние веб-сайты и приложения теперь могут позволять посетителям входить в систему, используя свои учетные записи пользователей Google. Федеративный вход в систему, основанный на стандарте OpenID, освобождает пользователей от необходимости создавать отдельные учетные записи для входа на разные веб-сайты - и освобождает разработчиков веб-сайтов от задачи реализации мер аутентификации при входе в систему. OpenID достигает этой цели, предоставляя структуру, в которой пользователи могут создать учетную запись у поставщика OpenID, такого как Google, и использовать эту учетную запись для входа на любой веб-сайт, который принимает OpenID. На этой странице описывается, как интегрировать систему интегрированного входа Google для веб-сайта или приложения.

https://developers.google.com/accounts/docs/OpenID

Возвращайся, когда застрянешь!

person Blundell    schedule 01.04.2012
comment
OpenID 2.0 устарел, проверьте developers.google.com/accounts/docs/OAuth2Login. - person mjn; 07.11.2014

Вы не можете точно войти в приложение Android с помощью учетной записи Google. Вы используете учетную запись Google для входа на веб-сайт или веб-службу, такую ​​как GMail, Календарь и т. Д., Или на сторонний веб-сайт, если используете OpenID. Поскольку ваше приложение не является веб-сайтом, это не сработает. Вы можете выполнить одно из следующих действий:

  • проверьте, зарегистрировал ли пользователь учетную запись Google (используя AccountManager) на своем телефоне, и разрешите им использовать приложение, только если оно у них есть. Если учетная запись зарегистрирована, вы можете быть уверены, что они знают пароль (или они украли чей-то телефон ...)
  • создать собственный веб-сервис (например, с помощью AppEngine), который использует ваше приложение, и использовать учетные записи Google для входа в него
person Nikolay Elenkov    schedule 02.04.2012

Поскольку руководство разработчика Android немного скудно о том, как реализовать вход в Google. Вот что я закончил после 3 дней обширных исследований, проб и ошибок.

с помощью приведенного ниже кода вы сможете получить из Google следующие

  • имя пользователя
  • электронное письмо
  • URL фотографии
  • полное имя

Для аутентификации и взаимодействия с API Google+ необходимо создать проект Google Developers Console, в котором необходимо включить API Google+ и создайте идентификатор клиента OAuth 2.0.

Перейдите в консоль разработчика Google. и создать новый проект

  1. Когда вы закончите создание проекта, нажмите API в разделе API и аутентификации. Найдите API Google+ и выберите тот, который я показал на изображении ниже.
  2. Включите Google+ API, нажав кнопку «Включить API».
  3. После включения перейдите в раздел «Учетные данные» в API и создайте новый идентификатор клиента.
  4. В зависимости от типа разрабатываемого приложения вам может потребоваться создать идентификатор клиента Android или идентификатор веб-клиента (в моем случае было достаточно идентификатора веб-клиента)
  5. замените ниже, где у него ADD_YOUR_OWN_CLIENT_ID вашим идентификатором!

Теперь код, сначала вспомогательный класс:

    public class GooglePlusSignInHelper {
    private final static String TAG = "GooglePlusSignInHelper";
        private final static int RC_SIGN_IN = 100;
        private static GoogleSignInOptions gso;

        private static GooglePlusSignInHelper sInstance;
        private static String webClientID;
        public GoogleApiClient googleApiClient;
        private Context context;
        private OnGoogleSignInListener loginResultCallback;
        private ResultCallback<Status> logoutResultCallback;

        public String signOutType ="";
    /**
     * This method should be called before calling any instance.
     * This is neccessary to get access token and id of user.
     * @param googleClientId
     */
    public static void setClientID(String googleClientId) {
        webClientID = googleClientId;
    }

    /**
     * Interface to listen to the Google login
     */
    public interface OnGoogleSignInListener {
        void OnGSignSuccess(GoogleSignInAccount googleSignInAccount, @Nullable Person person);

        void OnGSignError(GoogleSignInResult errorMessage);
    }

        public static GooglePlusSignInHelper getInstance() {
            if (sInstance == null) {
                sInstance = new GooglePlusSignInHelper();
            }
            return sInstance;
        }

        private GooglePlusSignInHelper() {
            // Configure sign-in to request the user's ID, email address, and basic
            // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
            gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestScopes(new Scope(Scopes.PLUS_LOGIN))
                    .requestProfile() //for profile related info
                    .requestEmail() //for email
                    .requestIdToken(webClientID) //for accessToken and id
                    .build();
        }

        public void initialize(FragmentActivity activity, OnGoogleSignInListener onGoogleSignInListener)
        {
            loginResultCallback = onGoogleSignInListener;
            context = activity;
            googleApiClient = new GoogleApiClient.Builder(activity)
                    .enableAutoManage(activity /* FragmentActivity */, new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) {
                            Log.e(TAG, "onConnectionFailed: " + connectionResult);
                        }
                    } /* OnConnectionFailedListener */)
                    .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                    .addApi(Plus.API)
                    .build();

            googleApiClient.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle bundle) {
                    Log.i(TAG, "onConnected");
                }

                @Override
                public void onConnectionSuspended(int i) {
                    Log.i(TAG, "onConnectionSuspended");
                }
            });

            googleApiClient.registerConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
                    Log.i(TAG, "onConnectionFailed");
                }
            });

        }

        public boolean isConnected() {
            boolean isConnected = googleApiClient.isConnected();

            Log.i(TAG, "isConnected()" + isConnected);
            return isConnected;
        }

        public void signIn(Activity activity) {

            if (googleApiClient.isConnected()) {
                if (!googleApiClient.hasConnectedApi(Auth.GOOGLE_SIGN_IN_API)) {
                    googleApiClient.clearDefaultAccountAndReconnect();
                }
                Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
                        new ResultCallback<Status>() {
                            @Override
                            public void onResult(Status status) {
                                if (!signOutType.equals("silent")) {
                                    Toast.makeText(activity, "Logged Out", Toast.LENGTH_SHORT).show();
                                }
                                signOutType="";
                                startActivity(activity);
                            }
                        });
            } else {
                googleApiClient.connect();
                startActivity(activity);
            }
        }

        private void startActivity(Activity activity){
            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
            activity.startActivityForResult(signInIntent, RC_SIGN_IN);
        }

        public void signOut() {
            if (!isConnected())
                return;

            Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            if (logoutResultCallback != null) {
                                logoutResultCallback.onResult(status);
                            }
                        }
                    });
        }

        private void handleSignInResult(GoogleSignInResult result) {
            Log.d(TAG, "handleSignInResult:" + result.isSuccess());
            if (result.isSuccess()) {
                Log.i(TAG, "Signed in");
                // Signed in successfully, show authenticated UI.
                final GoogleSignInAccount acct = result.getSignInAccount();

                //This code is just for getting google plus information like gender, birthday, aboutme etc
                final Person[] person = {null};
                if(acct!=null) {
                    Plus.PeopleApi.load(googleApiClient, acct.getId()).setResultCallback(new ResultCallback<People.LoadPeopleResult>() {
                        @Override
                        public void onResult(@NonNull People.LoadPeopleResult loadPeopleResult) {
                            try {
                                person[0] = loadPeopleResult.getPersonBuffer().get(0);
                                loadPeopleResult.getPersonBuffer().release();
                            } catch (Exception e){
                                if (loginResultCallback != null) {
                                    loginResultCallback.OnGSignError(result);
                                }
                            }
                            finally {
                                if (loginResultCallback != null) {
                                    loginResultCallback.OnGSignSuccess(acct, person[0]);
                                }
                            }
                        }
                    });
                }
//                If you don't want google+ related info, just comment above code, uncomment below callback
//                if (loginResultCallback != null) {
//                    //In this case, person object will always be null
//                    loginResultCallback.OnGSignSuccess(acct, null);
//                }

            } else {
                Log.i(TAG, "Signed out");

                if (loginResultCallback != null) {
                    loginResultCallback.OnGSignError(result);
                }
            }
        }

        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
            if (requestCode == RC_SIGN_IN) {
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
                handleSignInResult(result);
            }
        }

        public void setLogoutResultCallback(ResultCallback<Status> callback) {
            logoutResultCallback = callback;
        }
}

Предполагая, что у вас есть фрагмент, загруженный внутри действия. В моем случае загруженный фрагмент называется FragmentCreateAccount. Добавьте следующее к классу активности (не к классу фрагмента):

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        FragmentCreateAccount fragmentCreateAccount = (FragmentCreateAccount) getSupportFragmentManager().findFragmentById(R.id.frgament_settings_content_frame);
        if(fragmentCreateAccount!=null)
        {
            fragmentCreateAccount.onActivityResult(requestCode, resultCode, data);
        }
    }

Наконец, в классе активности фрагмента сначала необходимо объявить следующее

private ImageButton googleSignInButton;
private GooglePlusSignInHelper gSignInHelper;

ProgressBar progressBar;

Затем, также внутри класса активности Fragment, добавьте следующее:

   @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
       // ...

        googleSignInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                progressBar.setVisibility(View.VISIBLE);
                gSignInHelper.signOutType="silent";
                gSignInHelper.signIn(getActivity());
            }
        });

        GooglePlusSignInHelper.setClientID(ADD_YOUR_OWN_CLIENT_ID);
        gSignInHelper = GooglePlusSignInHelper.getInstance();
        gSignInHelper.initialize(getActivity(),  this);
        gSignInHelper.signOutType="silent";

// ...

    }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    gSignInHelper.onActivityResult(requestCode, resultCode, data);
    progressBar.setVisibility(View.GONE);

}

/****************** Google Sign In *******************************************/
@Override
public void OnGSignSuccess(GoogleSignInAccount acct, Person person) {
    try {
        String GuserName = (acct.getDisplayName()==null)?"":acct.getDisplayName();
        String Gemail = acct.getEmail();

        email.setText(Gemail);
        String[] params= new String[4];
        params[0]=GuserName;
        params[1]=Gemail;
        params[2]="";
        params[3]="";

        if (person != null) {
            int gender = person.getGender();
            String sGender="";
            if (gender == 0)
                sGender = "MALE";
            else if (gender == 1)
                sGender = "FEMALE";
            else
                sGender = "OTHERS";

            String GpersonName = person.getDisplayName();
            String GpersonPhotoUrl = person.getImage().getUrl();

            Log.e(TAG, "Name: " + GpersonName + ", email: " + Gemail + ", Image: " + GpersonPhotoUrl);

            params[2]=GpersonName;
            params[3]=GpersonPhotoUrl;

            //personPhotoUrl = personPhotoUrl.substring(0, personPhotoUrl.length() - 2)  + PROFILE_PIC_SIZE;
            //new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
        } else if(SessionData.System.isDebugEnabled) {
            Toast.makeText(getActivity(), "Couldnt Get the Person Info", Toast.LENGTH_SHORT).show();
        }
        Toast.makeText(getActivity(), "You are Logged In " + GuserName,Toast.LENGTH_LONG).show();
        
        // ...
    } catch (Exception e) {
        CrashReports crashReports = new CrashReports();
        crashReports.SaveCrash(e, getActivity());
    }
}

@Override
public void OnGSignError(GoogleSignInResult errorMessage) {
    // status code 12501 : canceled by user
    if (errorMessage.getStatus().getStatusCode()==12501){
        // TODO: language translation
        Toast.makeText(getActivity(), "Google auth canceled", Toast.LENGTH_SHORT).show();
    }else{
        Toast.makeText(getActivity(), errorMessage.getStatus().zzg(), Toast.LENGTH_SHORT).show();
    }
}

Вам также необходимо добавить в файл манифеста следующее:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

и в файле build.gradle (app):

implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.google.android.gms:play-services-plus:17.0.0'

Последнее примечание: этот код работает на Android Studio 4.2 canary 15, Gradle 4.2.0-alpha15 и SDK 29.

person Miguel Silva    schedule 25.02.2021