Android - 使用登录屏幕代替自动登录的 Google 登录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23872051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:33:43  来源:igfitidea点击:

Android - Google Login with Login-Screen instead of Automatic Login

androidlogingoogle-plusgoogle-play-servicesgoogle-api-client

提问by Kevin Cruijssen

I've added a Google log-in to my Android App (steps can be found at edit 3 of this post). Everything works as it should, but I'd like to make some small adjustments. With the current code found at edit 3, you are automatically logged in every time you start the app, without the Log-in Screen. I want to disable this, since the app will be used on a tablet at work, where a different employee should Login to the app every day.

我已经在我的 Android 应用程序中添加了一个谷歌登录(步骤可以在这篇文章的第 3 部分找到)。一切正常,但我想做一些小的调整。使用在编辑 3 中找到的当前代码,您每次启动应用程序时都会自动登录,没有登录屏幕。我想禁用它,因为该应用程序将在工作中的平板电脑上使用,不同的员工应该每天登录该应用程序。

I started by removing the mGoogleApiClient.connect();from the onStart()method, and now I have the Google Login button again. When I add mGoogleApiClient.connect();to the signInWithGoogle()I'm able to sign in with the remembered user.

我首先mGoogleApiClient.connect();onStart()方法中删除了,现在我又有了 Google 登录按钮。当我添加mGoogleApiClient.connect();到 时,signInWithGoogle()我可以使用记住的用户登录。

What I want right now is the default Google Login screen where you can fill in your Google-Email and Password, every time you click on the Login Button, instead of just logging-in the remembered user. (PS: Keep in mind that on my Android Device I currently only have one user at Settings -> Google Accounts, maybe that's why it automatically logs in instead of giving the option to choose which account should be connecting.)

我现在想要的是默认的谷歌登录屏幕,你可以在每次点击登录按钮时填写你的谷歌电子邮件和密码,而不是仅仅登录记住的用户。(PS:请记住,在我的 Android 设备上,我目前只有一个用户在Settings -> Google Accounts,也许这就是为什么它会自动登录而不是提供选择应该连接哪个帐户的选项。)

I will test if it makes a different when I have multiple Google Accounts on my Android Device.Ok, I've added a second Google Account to my Android Device, but my app still automatically logs in the remembered user when I click on Sign-In..

当我的 Android 设备上有多个 Google 帐户时,我会测试它是否会有所不同。好的,我已经向我的 Android 设备添加了第二个 Google 帐户,但是当我点击登录时,我的应用程序仍然会自动登录记住的用户。



EDIT 2:

编辑2:

I haven't been able to find a solution for my problem yet.

我还没有找到解决我的问题的方法。

I did find some more tutorials with different ways to log-in to Google, like using the AccountManagerso a user can select one of the existing Google Accounts on the device. (I've only read about this method today, so don't have any code examples for this yet. But this also isn't what I'm looking for anyway.)

我确实找到了更多使用不同方式登录 Google 的教程,例如使用AccountManager以便用户可以选择设备上现有的 Google 帐户之一。(我今天只阅读了这种方法,所以还没有任何代码示例。但这也不是我要找的东西。)

I probably already made it clear in the post above, but this is what I want explained in pictures:

我可能已经在上面的帖子中说清楚了,但这就是我想要在图片中解释的内容:

  1. A User starts the app on his/her Android Device.
  2. A User puts in his Google-Account username (used e-mail) and password List item
  3. After a user is successfully logged in, we can do other things with the app
  1. 用户在他/她的 Android 设备上启动应用程序。
  2. 用户输入他的 Google 帐户用户名(使用的电子邮件)和密码 项目清单
  3. 用户登录成功后,我们可以用app做其他事情

PS: Just to make sure, this Log-in screen is the one of Google itself. So it's not a Login screen created by myself. This would in theory make me able to save the entered password, which is against protocol of Google OAuth.

PS:为了确保,这个登录屏幕是 Google 自己的。所以它不是我自己创建的登录屏幕。理论上,这将使我能够保存输入的密码,这违反了 Google OAuth 的协议。



EDIT 3 (The Code):

编辑 3(代码):

Steps I did to make Google Services work so far are below. Now I just need to figure out how to either force the log-in screen or completely log-out which results in the log-in screen every time.

到目前为止,我为使 Google 服务正常工作所做的步骤如下。现在我只需要弄清楚如何强制登录屏幕或完全注销每次都会导致登录屏幕。

I've followed the following tutorial: http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/

我遵循了以下教程:http: //www.androidhive.info/2014/02/android-login-with-google-plus-account-1/

With extra info used from the following tutorials/sites:

使用来自以下教程/站点的额外信息:

This generated the following code:

这生成了以下代码:

AndroidManifest.xml:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testproject_gmaillogin"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="19" />

    <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="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

        <activity
            android:name="com.example.testproject_gmaillogin.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>

strings.xml:

字符串.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">TestProject_GmailLogin</string>
    <string name="action_settings">Settings</string>

    <string name="profile_pic_description">Google Profile Picture</string>
    <string name="btn_logout_from_google">Logout from Google</string>
    <string name="btn_revoke_access">Revoke Access</string>

</resources>

activity_main.xml:

活动_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/profile_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:orientation="horizontal"
        android:weightSum="3"
        android:visibility="gone">

        <ImageView
            android:id="@+id/img_profile_pic"
            android:contentDescription="@string/profile_pic_description"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:orientation="vertical"
            android:layout_weight="2" >

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

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

    <com.google.android.gms.common.SignInButton
        android:id="@+id/btn_sign_in"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"/>

    <Button
        android:id="@+id/btn_sign_out"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_logout_from_google"
        android:visibility="gone"
        android:layout_marginBottom="10dp"/>

    <Button
        android:id="@+id/btn_revoke_access"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_revoke_access"
        android:visibility="gone" />

</LinearLayout>

MainActivity.java:

主活动.java:

package com.example.testproject_gmaillogin;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, OnClickListener
{
    // Logcat tag
    private static final String TAG = "MainActivity";

    // Profile pix image size in pixels
    private static final int PROFILE_PIC_SIZE = 400;

    // Request code used to invoke sign in user interactions
    private static final int RC_SIGN_IN = 0;

    // Client used to interact with Google APIs
    private GoogleApiClient mGoogleApiClient;

    // A flag indicating that a PendingIntent is in progress and prevents
    // us from starting further intents
    private boolean mIntentInProgress;

    // Track whether the sign-in button has been clicked so that we know to resolve
    // all issues preventing sign-in without waiting
    private boolean mSignInClicked;

    // Store the connection result from onConnectionFailed callbacks so that we can
    // resolve them when the user clicks sign-in
    private ConnectionResult mConnectionResult;

    // The used UI-elements
    private SignInButton btnSignIn;
    private Button btnSignOut, btnRevokeAccess;
    private ImageView imgProfilePic;
    private TextView txtName, txtEmail;
    private LinearLayout profileLayout;

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

        // Get the UI-elements
        btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
        btnSignOut = (Button) findViewById(R.id.btn_sign_out);
        btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
        imgProfilePic = (ImageView) findViewById(R.id.img_profile_pic);
        txtName = (TextView) findViewById(R.id.txt_name);
        txtEmail = (TextView) findViewById(R.id.txt_email);
        profileLayout = (LinearLayout) findViewById(R.id.profile_layout);

        // Set the Button onClick-listeners
        btnSignIn.setOnClickListener(this);
        btnSignOut.setOnClickListener(this);
        btnRevokeAccess.setOnClickListener(this);

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

    @Override
    protected void onStart(){
        super.onStart();
        mGoogleApiClient.connect(); // <- REMOVED (EDIT 4: Added again)
    }

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

        if(mGoogleApiClient.isConnected())
            mGoogleApiClient.disconnect();
    }

    @Override
    public void onClick(View view){
        switch(view.getId()){
            case R.id.btn_sign_in:
                signInWithGPlus();
                break;
            case R.id.btn_sign_out:
                signOutFromGPlus();
                break;
            case R.id.btn_revoke_access:
                revokeGPlusAccess();
                break;
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        if(!result.hasResolution()){
            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
            return;
        }

        if(!mIntentInProgress){
            // Store the ConnectionResult so that we can use it later when the user clicks 'sign-in'
            mConnectionResult = result;

            if(mSignInClicked)
                // The user has already clicked 'sign-in' so we attempt to resolve all
                // errors until the user is signed in, or they cancel
                resolveSignInErrors();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int responseCode, Intent intent){
        if(requestCode == RC_SIGN_IN && responseCode == RESULT_OK)
            SignInClicked = true;

            mIntentInProgress = false;

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

    @Override
    public void onConnected(Bundle connectionHint) {
        mSignInClicked = false;
        Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();

        // Get all the user's information
        getProfileInformation();

        // Update the UI after sign-in
        updateUI(true);
    }

    @Override
    public void onConnectionSuspended(int cause){
        mGoogleApiClient.connect();
        updateUI(false);
    }

    // Updating the UI, showing/hiding buttons and profile layout
    private void updateUI(boolean isSignedIn){
        if(isSignedIn){
            btnSignIn.setVisibility(View.GONE);
            btnSignOut.setVisibility(View.VISIBLE);
            btnRevokeAccess.setVisibility(View.VISIBLE);
            profileLayout.setVisibility(View.VISIBLE);
        }
        else{
            btnSignIn.setVisibility(View.VISIBLE);
            btnSignOut.setVisibility(View.GONE);
            btnRevokeAccess.setVisibility(View.GONE);
            profileLayout.setVisibility(View.GONE);
        }
    }

    // Sign-in into Google
    private void signInWithGPlus(){
        //if(!mGoogleApiClient.isConnecting()) // <- ADDED (EDIT 4: Removed again)
            //mGoogleApiClient.connect(); // <- ADDED (EDIT 4: Removed again)

        if(!mGoogleApiClient.isConnecting()){
            mSignInClicked = true;
            resolveSignInErrors();
        }
    }

    // Method to resolve any sign-in errors
    private void resolveSignInErrors(){
        if(mConnectionResult.hasResolution()){
            try{
                mIntentInProgress = true;

                //Toast.makeText(this, "Resolving Sign-in Errors", Toast.LENGTH_SHORT).show();

                mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
            }
            catch(SendIntentException e){
                // The intent was cancelled before it was sent. Return to the default
                // state and attempt to connect to get an updated ConnectionResult
                mIntentInProgress = false;
                mGoogleApiClient.connect();
            }
        }
    }

    // Fetching the user's infromation name, email, profile pic
    private void getProfileInformation(){
        try{
            if(Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null){
                Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
                String personName = currentPerson.getDisplayName();
                String personPhotoUrl = currentPerson.getImage().getUrl();
                String personGooglePlusProfile = currentPerson.getUrl();
                String personEmail = Plus.AccountApi.getAccountName(mGoogleApiClient);

                Log.e(TAG, "Name: " + personName + ", "
                        + "plusProfile: " + personGooglePlusProfile + ", "
                        + "email: " + personEmail + ", "
                        + "image: " + personPhotoUrl);

                txtName.setText(personName);
                txtEmail.setText(personEmail);

                // by default the profile url gives 50x50 px image,
                // but we can replace the value with whatever dimension we
                // want by replacing sz=X
                personPhotoUrl = personPhotoUrl.substring(0, personPhotoUrl.length() - 2)
                        + PROFILE_PIC_SIZE;

                new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
            }
            else{
                Toast.makeText(getApplicationContext(), "Person information is null", Toast.LENGTH_LONG).show();
            }
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }

    // Sign-out from Google
    private void signOutFromGPlus(){
        if(mGoogleApiClient.isConnected()){
            Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
            mGoogleApiClient.disconnect();
            mGoogleApiClient.connect();
            updateUI(false);
        }
    }

    // Revoking access from Google
    private void revokeGPlusAccess(){
        if(mGoogleApiClient.isConnected()){
            Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
            Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
                .setResultCallback(new ResultCallback<Status>(){
                    @Override
                    public void onResult(Status s){
                        Log.e(TAG, "User access revoked!");
                        mGoogleApiClient.connect();
                        updateUI(false);
                    }
                });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings)
            return true;

        return super.onOptionsItemSelected(item);
    }
}

LoadProfileImage.java:

LoadProfileImage.java:

package com.example.testproject_gmaillogin;

import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

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

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

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

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

The other steps I did were:

我做的其他步骤是:

At https://console.developers.google.com/projectI've created a project with:

https://console.developers.google.com/project我创建了一个项目:

Google+ API on:

Google+ API 在:

Google+ API on

Google+ API 上

And a Client ID created with the correct SHA1 and exact same namespace as the project:

以及使用正确的 SHA1 和与项目完全相同的命名空间创建的客户端 ID:

And a Client ID created with the correct SHA1

以及使用正确的 SHA1 创建的客户端 ID

At Eclipse:

在日食:

I've installed the google-play-services library:

我已经安装了 google-play-services 库:

Google-play services installed

已安装 Google 播放服务

And added it to the project:

并将其添加到项目中:

Google-play services library added (2)Google-play services library added (2)

添加了 Google-play 服务库 (2)添加了 Google-play 服务库 (2)

I've also created an Emulator with version Google 4.4.2 (so not Android 4.4.2) and also changed the Project to Google 4.4.2 instead of Android 4.4.2:

我还创建了一个版本为 Google 4.4.2(所以不是 Android 4.4.2)的模拟器,并将项目更改为 Google 4.4.2 而不是 Android 4.4.2:

Solution ErrorSolution Error Emulator

解决方案错误解决方案错误模拟器



EDIT 4:

编辑 4:

Ok, I have a temporary solution for my own case. In my case the app I'm making should run on a Tablet which is used explicitly for my App. Because this is the case, I can remove all the Google Accounts from the Device Settings the moment someone revokes access (as log out function).

好的,我有一个针对我自己情况的临时解决方案。在我的情况下,我正在制作的应用程序应该在明确用于我的应用程序的平板电脑上运行。在这种情况下,我可以在有人撤销访问权限时从设备设置中删除所有 Google 帐户(作为注销功能)。

I started by removing the previous changes (re-added the .connect();to the onStart()and removed it from the signInWithGPlus())

我首先删除以前的更改(将 重新添加.connect();onStart()并将其从 中删除signInWithGPlus()

Then I added one line to the revokeGPlusAccess-method:

然后我在revokeGPlusAccess-method 中添加了一行:

// Revoking access from Google
private void revokeGPlusAccess(){
    if(mGoogleApiClient.isConnected()){
        Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
        Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
            .setResultCallback(new ResultCallback<Status>(){
                @Override
                public void onResult(Status s){
                    Log.e(TAG, "User access revoked!");
                    removeAllGoogleAccountsFromDevice(); // <- Added
                    mGoogleApiClient.connect();
                    updateUI(false);
                }
            });
    }
}

With the following method:

使用以下方法:

// Method to remove ALL Google Accounts from the Android Device
private void removeAllGoogleAccountsFromDevice(){
    // Ask if this really is what you want
    new AlertDialog.Builder(MainActivity.mActivity)
        .setMessage("Are you sure you want to delete all Google Accounts from this Android Device?\r\n\r\n" +
                "WARNING: If you run this app on the Work Tablet, click YES. If you run this on your own device, it's recommended to click NO.")
        .setCancelable(false)
        .setPositiveButton("Yes, continue", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // AccountManager is final because we use it in the separate Thread below
                final AccountManager accountManager = AccountManager.get(MainActivity.this);
                Account[] googleAccounts = accountManager.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
                // Account is final because we use it in the separate Thread below
                for(final Account a : googleAccounts){
                    // Separate Thread because AccountManager #removeAccount is an async operation
                    Thread worker = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            accountManager.removeAccount(a, null, null);
                        }
                    });
                    worker.start();
                }
            }
        })
        .setNegativeButton("No", null)
        .show();
}

Still, this only works in my case. This won't work on a personal device where you obviously don't want to delete all the Device's Google Accounts. I would still like to know a solution when you don't want to delete any Device's Google Accounts.

尽管如此,这只适用于我的情况。这不适用于您显然不想删除所有设备的 Google 帐户的个人设备。当您不想删除任何设备的 Google 帐户时,我仍然想知道一个解决方案。

回答by wittyurchin

The correct answer is here.

正确答案在这里

One needs to call mClient.clearDefaultAccountAndReconnect()to clear previously cached account.
It is a good practice to do this everytime a user clicks the sign in button, so that user is shown all his accounts everytime.

需要调用mClient.clearDefaultAccountAndReconnect()清除以前缓存的帐户。
每次用户单击登录按钮时都执行此操作是一种很好的做法,以便用户每次都能看到他的所有帐户。

回答by class

Try signing out the userand then signing the user in again. If you wanted to force the user to sign in every time, you could just sign them out whenever they exit the app. I don't recommend you change the app sign-out behavior because it could surprise the user.

尝试注销用户,然后再次登录用户。如果您想强制用户每次都登录,您可以在他们退出应用程序时将其注销。我不建议您更改应用程序退出行为,因为这可能会让用户感到惊讶。

Make sure your developer environment is set up correctly by running the Google+ Android Quickstart sample. If the signin behavior in the sample app is the same as you're seeing, either there is an issue with your development environment (e.g. GMS version, Android API version) or the Sign-In button behavior is not what you expect it to be.

通过运行 Google+ Android 快速入门示例确保您的开发人员环境设置正确。如果示例应用程序中的登录行为与您看到的相同,要么是您的开发环境(例如 GMS 版本、Android API 版本)存在问题,要么是登录按钮行为与您的预期不符.

Finally, you might be able to benefit from this article which covers a few common problem spots with Android Sign-In. It covers a high-level view of the various authorization and resolution steps in the Android Sign-In flow.

最后,您可能会从这篇涵盖 Android 登录的一些常见问题点的文章中受益。它涵盖了 Android 登录流程中各种授权和解决步骤的高级视图。

回答by Sagar Maiyad

Sign outwill not help you to solve your problem. you have to revoke accessevery time whenever you exit from the app or whenever you want to signout from the app and login again. so, just call revoke accessmethod in backpressedmethod at exit app like below:

注销不会帮助您解决问题。每当您退出应用程序或想要退出应用程序并再次登录时,您都必须撤销访问权限。因此,只需在退出应用程序的backpressed方法中调用revoke 访问方法,如下所示:

 @Override
    public void onBackPressed() {
       Log.d("CDA", "onBackPressed Called");
       revokeGplusAccess();
       super.onBackPressed();
    }

This will definitely solve your issue.

这绝对可以解决您的问题。