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

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

8 ответов

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

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

Загрузить образец из Google - Android SDK Manager / Дополнительно / Сервисы Google Play

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

  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. Next Back-end сервер отвечает приложению, делать ли пользователю вход в систему или нет.

Ниже приведен формат ответа на вышеуказанный вызов 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 ";

в

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

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

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

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

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

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, в котором необходимо включить API-интерфейс Google+ и создать идентификатор клиента OAuth 2.0.

  1. Перейти к консоли разработчиков Google. и создать новый проект
  2. Как только вы закончите создание проекта, нажмите на API в разделе API и Auth. Найдите Google+ API и выберите тот, который я показал на изображении ниже.
  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+ Login. Для более подробной информации вы можете посетить здесь.

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

Вот как я интегрирую логин Google с последним и самым плавным способом.

Из этой ссылки: Google LoginAndroid 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) {

    }
}
    **Dependency**
    **Need Internet Permission** 

**Working Code   see Link on  play Store**
https://play.google.com/store/search?q=com.codecube.airbucks

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


    <?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">


        <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>

    package com.keshav.geofencing;

    import android.Manifest;
    import android.annotation.TargetApi;
    import android.app.ProgressDialog;
    import android.content.BroadcastReceiver;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v4.content.LocalBroadcastManager;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    import com.facebook.CallbackManager;
    import com.facebook.FacebookCallback;
    import com.facebook.FacebookException;
    import com.facebook.FacebookSdk;
    import com.facebook.GraphRequest;
    import com.facebook.GraphResponse;
    import com.facebook.login.LoginManager;
    import com.facebook.login.LoginResult;
    import com.google.android.gms.appindexing.Action;
    import com.google.android.gms.appindexing.AppIndex;
    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.GoogleApiAvailability;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.common.api.OptionalPendingResult;
    import com.google.android.gms.common.api.ResultCallback;
    import com.google.android.gms.common.api.Status;

    import org.json.JSONException;
    import org.json.JSONObject;

    import java.util.Arrays;

    import utilities.CommonMethod;
    import utilities.LoginPreferences;


    public class LoginWithGmail extends AppCompatActivity
            implements GoogleApiClient.OnConnectionFailedListener {

        private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
        private static final String TAG = "LoginActivity";
        private static final int RC_SIGN_IN = 9001;
        Button loginSub;
        LinearLayout signInButton;


        String gmailId;
        String gmailName;
        String gmailUserEmailId;
        Uri gmailUserPhoto;
        String savePassword;
        LinearLayout btnlogin;
        TextView btnsigning;
        ProgressDialog prgDialog;

        private CallbackManager callbackManager;

        private BroadcastReceiver mRegistrationBroadcastReceiver;
        private LinearLayout fbloginButton;
    //    private CallbackManager callbackManager;
        private ProgressDialog mProgressDialog;
        private GoogleApiClient mGoogleApiClient;

        EditText edtEmail;

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

            checkPermission();

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

            mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .addApi(AppIndex.API).build();


            // Google Sign up Button
            signInButton = (LinearLayout) findViewById(R.id.sign_in_button);

            signInButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        int permissionCheck = ContextCompat.checkSelfPermission(LoginWithGmail.this, Manifest.permission.CAMERA);
                        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                            //showing dialog to select image

                            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                            signInIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                            startActivityForResult(signInIntent, RC_SIGN_IN);
                            Log.e("permission", "granted");
                        } else {
                            ActivityCompat.requestPermissions(LoginWithGmail.this,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                                            Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
                        }
                    } else {
                        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                        signInIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivityForResult(signInIntent, RC_SIGN_IN);
                    }

                }
            });

        }

        public void checkPermission() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                int permissionCheck = ContextCompat.checkSelfPermission(LoginWithGmail.this,
                        Manifest.permission.CAMERA);

                if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                    //showing dialog to select image
                    if (CommonMethod.isNetworkAvailable(LoginWithGmail.this)) {
                        Log.e("keshav", "Permission if part marsh");
                    } else {
                        CommonMethod.showAlert("Internet Connectivity Failure", LoginWithGmail.this);
                    }

                    Log.e("keshav", "permission granted");
                } else {
                    ActivityCompat.requestPermissions(LoginWithGmail.this,
                            new String[]{Manifest.permission.CAMERA,
                                    Manifest.permission.ACCESS_FINE_LOCATION,
                                    Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
                }
            }
        }

        @Override
        protected void onResume() {
            super.onResume();
    //        LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
    //                new IntentFilter(QuickstartPreferences.REGISTRATION_COMPLETE));
        }

        @Override
        protected void onPause() {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
            super.onPause();
        }


        @Override
        public void onBackPressed() {
            super.onBackPressed();

        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {

            if (requestCode == RC_SIGN_IN) {
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
                handleSignInResult(result);
            }
        }

        // TODO ADD ME

        @Override
        public void onStart() {
            super.onStart();

            OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
            if (opr.isDone()) {
                // If the user's cached credentials are valid, the OptionalPendingResult will be "done"
                // and the GoogleSignInResult will be available instantly.
                Log.e(TAG, "Got cached sign-in");
                GoogleSignInResult result = opr.get();
                handleSignInResult(result);
            } else {
                // If the user has not previously signed in on this device or the sign-in has expired,
                // this asynchronous branch will attempt to sign in the user silently.  Cross-device
                // single sign-on will occur in this branch.
                showProgressDialog();
                opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
                    @Override
                    public void onResult(GoogleSignInResult googleSignInResult) {
                        hideProgressDialog();
                        handleSignInResult(googleSignInResult);
                    }
                });
            }
        }

        // [START signOut]
        private void signOut() {
            Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            // [START_EXCLUDE]
    //                        updateUI(false);
                            // [END_EXCLUDE]
                        }
                    });
        }
        // [END signOut]

        // [START revokeAccess]
        private void revokeAccess() {
            Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
                    new ResultCallback<Status>() {
                        @Override
                        public void onResult(Status status) {
                            // [START_EXCLUDE]
    //                        updateUI(false);
                            // [END_EXCLUDE]
                        }
                    });
        }
        // [END revokeAccess]

        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            // An unresolvable error has occurred and Google APIs (including Sign-In) will not
            // be available.
            Log.e(TAG, "onConnectionFailed:" + connectionResult);
        }

        private void showProgressDialog() {
            if (mProgressDialog == null) {
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Loading...");
                mProgressDialog.setIndeterminate(true);
            }
            if (LoginWithGmail.this != null && mProgressDialog != null && !mProgressDialog.equals("null"))
                mProgressDialog.show();
        }

        private void hideProgressDialog() {
            if (mProgressDialog != null && mProgressDialog.isShowing()&& !mProgressDialog.equals("null")) {
                mProgressDialog.hide();
            }
        }


        // TODO ADD ME ENd


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

                gmailId = acct.getId();
                gmailName = acct.getDisplayName();
                gmailUserEmailId = acct.getEmail();
                gmailUserPhoto = acct.getPhotoUrl();

                Log.e("gmailId", "is -->" + gmailId);
                Log.e("gmailName", "is -->" + gmailName);
                Log.e("gmailUserEmailId", "is -->" + gmailUserEmailId);
                Log.e("gmailUserPhoto", "is -->" + gmailUserPhoto);

                LoginPreferences.getActiveInstance(LoginWithGmail.this).setUserName(gmailName);
                LoginPreferences.getActiveInstance(LoginWithGmail.this).setProfileImage(""+gmailUserPhoto);


                Log.e("information", "using Gmail is > " + gmailId + " " + gmailName + "" + gmailUserEmailId + "" + gmailUserPhoto);

                if (CommonMethod.isNetworkAvailable(LoginWithGmail.this)) {
                    Log.e("SignUp gmail", "Hit API..........................");
                    Intent i=new Intent(LoginWithGmail.this,DrawerActivity.class);
                    LoginPreferences.getActiveInstance(LoginWithGmail.this).setIsLoggedIn(true);
                    startActivity(i);
                    finish();

                    // TODO Here Registered User in own Database call Volley Retrofit2 Api ....
                    new SignUpSocialFacebookAsyncTask().execute();
                } else {
                    CommonMethod.showAlert("Intenet Connectivity Failure", LoginWithGmail.this);
                }

            } else {

            }
            // TODO ADD ME KESHAV Google GMail Logout
            Auth.GoogleSignInApi.signOut(mGoogleApiClient);
        }

        @Override
        public void onStop() {
            super.onStop();

            // ATTENTION: This was auto-generated to implement the App Indexing API.
            // See https://g.co/AppIndexing/AndroidStudio for more information.
            Action viewAction = Action.newAction(
                    Action.TYPE_VIEW, // TODO: choose an action type.
                    "Login Page", // TODO: Define a title for the content shown.
                    // TODO: If you have web page content that matches this app activity's content,
                    // make sure this auto-generated web page URL is correct.
                    // Otherwise, set the URL to null.
                    Uri.parse("http://host/path"),
                    // TODO: Make sure this auto-generated app deep link URI is correct.
                    Uri.parse("android-app://com.keshav.geofencing/http/host/path")
            );
            AppIndex.AppIndexApi.end(mGoogleApiClient, viewAction);
            mGoogleApiClient.disconnect();
        }

        //Todo  add new method for permission
        @TargetApi(Build.VERSION_CODES.M)
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            if (requestCode == RC_SIGN_IN) {
                Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                signInIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivityForResult(signInIntent, RC_SIGN_IN);

            }
        }

    }

    **Dependency**
    **Need Internet Permission** 

**Working Code   see Link on  play Store**
https://play.google.com/store/search?q=com.codecube.airbucks

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

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

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

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

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

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

Поскольку руководство разработчика 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.

Другие вопросы по тегам