如何记住登录 Google 帐户 Android

Posted

技术标签:

【中文标题】如何记住登录 Google 帐户 Android【英文标题】:How to Remember Sign In in Google Account Android 【发布时间】:2016-03-27 08:02:40 【问题描述】:

登录活动 请帮助我只是想在后台记住登录应用程序,以便当他重新打开应用程序时自动打开下一个活动而不是登录活动。

package xxx.xxxxx.xxxxxx;

/**
 * Created by Yoyo on 12/21/2015.
 */
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
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.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;

public class Login extends AppCompatActivity implements OnConnectionFailedListener, View.OnClickListener, ConnectionCallbacks 
    GoogleApiClient mGoogleApiClient;
    GoogleSignInOptions gso;
    SignInButton signIn_btn;
    private static final int RC_SIGN_IN = 0;
    ProgressDialog progress_dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        buidNewGoogleApiClient();
        setContentView(R.layout.login);
        customizeSignBtn();
        setBtnClickListeners();
        progress_dialog = new ProgressDialog(this);
        progress_dialog.setMessage("Signing in....");
    

    /*
    Configure sign-in to request the user's ID, email address, and basic profile.
    User's ID and basic profile are included in DEFAULT_SIGN_IN.
    create and  initialize GoogleApiClient object to use Google  Sign-In API and the options specified by gso..
    */

    private void buidNewGoogleApiClient()

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

    /*
      Customize sign-in button. The sign-in button can be displayed in
      multiple sizes and color schemes. It can also be contextually
      rendered based on the requested scopes. For example. a red button may
      be displayed when Google+ scopes are requested, but a white button
      may be displayed when only basic profile is requested. Try adding the
      Plus.SCOPE_PLUS_LOGIN scope to see the  difference.
    */

    private void customizeSignBtn()

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

    

    /*
      Set on click Listeners on the sign-in sign-out and disconnect buttons
     */

    private void setBtnClickListeners()
        // Button listeners
        signIn_btn.setOnClickListener(this);
        findViewById(R.id.sign_out_button).setOnClickListener(this);
        findViewById(R.id.disconnect_button).setOnClickListener(this);

    

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

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    

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

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) 
            if (resultCode != RESULT_OK) 

                progress_dialog.dismiss();

            
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            getSignInResult(result);
        
    

    @Override
    public void onClick(View v) 
        switch (v.getId()) 
            case R.id.sign_in_button:
                Toast.makeText(this, "start sign process", Toast.LENGTH_SHORT).show();
                gSignIn();
                break;
            case R.id.sign_out_button:
                Toast.makeText(this, "Google Sign Out", Toast.LENGTH_SHORT).show();
                gSignOut();
                break;
            case R.id.disconnect_button:
                Toast.makeText(this, "Google Access Revoked", Toast.LENGTH_SHORT).show();
                gRevokeAccess();
                break;
        
    

    private void gSignIn() 
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
        progress_dialog.show();
    

    private void gSignOut() 
        Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                new ResultCallback<Status>() 
                    @Override
                    public void onResult(Status status) 

                        updateUI(false);

                    
                );
    

    private void gRevokeAccess() 
        Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
                new ResultCallback<Status>() 
                    @Override
                    public void onResult(Status status) 

                        updateUI(false);

                    
                );
    

    private void getSignInResult(GoogleSignInResult result) 

        if (result.isSuccess()) 



            // Signed in successfully, show authenticated UI.
            GoogleSignInAccount acct = result.getSignInAccount();

            TextView user_name= (TextView)findViewById(R.id.userName);
            TextView email_id= (TextView)findViewById(R.id.emailId);
            user_name.setText("UserName: "+ acct.getDisplayName());
            email_id.setText("Email Id: " + acct.getEmail());
            updateUI(true);        

SharedPreferences sharedPreferences = getSharedPreferences("APP", MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean("isLogin", true);
            editor.putString("name", //Name),
             editor.putString("e_mail",
                            editor.putString("ID", //ID);
                                    editor.commit());



   progress_dialog.dismiss();
         else 
            // Signed out, show unauthenticated UI.
            updateUI(false);
        
    

    private void updateUI(boolean signedIn) 
        if (signedIn) 
            findViewById(R.id.sign_in_button).setVisibility(View.GONE);
            findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE);
         else 
            findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
            findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE);
        
    

    @Override
    public void onConnected(Bundle bundle) 

    

    @Override
    public void onConnectionSuspended(int i) 

    

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) 

    

Activity 的登录 xml 文件登录 xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="num.app.xxx.xxxx.xxxx.Login"
    tools:showIn="@layout/Login">

    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_
        android:layout_ />

    <LinearLayout
        android:id="@+id/sign_out_and_disconnect"
        android:layout_
        android:layout_
        android:orientation="vertical"
        android:visibility="gone"
        tools:visibility="visible"
        android:layout_centerHorizontal="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true">

        <TextView
            android:id="@+id/userName"
            android:layout_
            android:layout_
            android:text=" user name:"
            android:layout_marginTop="15dp"
            android:layout_marginLeft="10dp"
            android:textColor="@android:color/black"

            android:textSize="14sp"
            />

        <TextView
            android:id="@+id/emailId"
            android:layout_
            android:layout_
            android:text="email id:"
            android:textColor="@android:color/black"
            android:layout_below="@+id/userName"
            android:layout_marginTop="15dp"
            android:layout_marginLeft="10dp"
            android:textSize="14sp"
            />

        <Button
            android:id="@+id/sign_out_button"
            android:layout_
            android:layout_
            android:layout_gravity="center_vertical"
            android:text="Google Sign out"/>

        <Button
            android:id="@+id/disconnect_button"
            android:layout_
            android:layout_
            android:layout_gravity="center_vertical"
            android:text="revoke Google Access"/>

    </LinearLayout>

</RelativeLayout>

//在上述活动之前启动活动

   Thread timer = new Thread()
            public void run()

                try
                    sleep(1000);

                catch(InterruptedException e)
                    e.printStackTrace();
                finally



                    Intent openStartingPoint = new Intent("android.intent.action.Login");
                    startActivity(openStartingPoint);
                    finish();
                
            
        ;
        timer.start();

【问题讨论】:

获取到的信息,可以保存在SharedPreference,避免再次登录。并且如果用户注销了应用,可以清除SharedPreference的数据。 @NigamPatro 你能在编码中做一些修改来告诉我该怎么做吗? 您的应用程序中有启动画面吗? @NigamPatro 是的,最初的活动是启动登录活动的启动画面 那么,你看不懂哪一部分? 【参考方案1】:

我会避免将令牌保存在共享首选项中,而是尝试按照此处所述执行静默登录:http://android-developers.blogspot.de/2015/12/api-updates-for-sign-in-with-google.html

这样做的好处是可以让您验证用户是否仍然登录,并最终让您提示他请求重新登录。

这里有一些代码(基本上改编自链接中的示例):

public void silentLogin() 
    OptionalPendingResult<GoogleSignInResult> pendingResult = Auth.GoogleSignInApi.silentSignIn(googleApiClient);
    if (pendingResult != null) 
        handleGooglePendingResult(pendingResult);
     else 
        //no result from silent login. Possibly display the login page again 
    


private void handleGooglePendingResult(OptionalPendingResult<GoogleSignInResult> pendingResult) 
    if (pendingResult.isDone()) 
        // There's immediate result available.
        GoogleSignInResult signInResult = pendingResult.get();
        onSilentSignInCompleted(signInResult);
     else 
        // There's no immediate result ready,  waits for the async callback.
        pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() 
            @Override
            public void onResult(@NonNull GoogleSignInResult signInResult) 
                onSilentSignInCompleted(signInResult, callback);
            
        );
    


private void onSilentSignInCompleted(GoogleSignInResult signInResult) 
    GoogleSignInAccount signInAccount = signInResult.getSignInAccount();        
    if (signInAccount != null) 
            // you have a valid sign in account. Skip the login.

         else 
            // you don't have a valid sign in account. Eventually display the login page again
        

【讨论】:

【参考方案2】:

你可以试试这个:

用户登录成功后,您可以通过调用 GoogleSignInAccount 的 getIdToken() 方法将 id 令牌保存到 SharedPreferences。当用户重新打开时,您可以检查 id 令牌是否正在退出,然后忽略登录屏幕。

private void getSignInResult(GoogleSignInResult result) 

        if (result.isSuccess()) 

            // Signed in successfully, show authenticated UI.
            GoogleSignInAccount acct = result.getSignInAccount();

            String id_token = acct.getIdToken(); //add this code here to save it by use SharedPreferences 

            TextView user_name= (TextView)findViewById(R.id.userName);
            TextView email_id= (TextView)findViewById(R.id.emailId);
            user_name.setText("UserName: "+ acct.getDisplayName());
            email_id.setText("Email Id: " + acct.getEmail());
            updateUI(true);
            progress_dialog.dismiss();
         else 
            // Signed out, show unauthenticated UI.
            updateUI(false);
        
    

//save user login state id_token

private void saveLoginState(String id_token)

   SharedPreferences sharedpreferences = getSharedPreferences("YOUR_PREFERENCE_NAME", Context.MODE_PRIVATE);    

SharedPreferences.Editor editor = sharedpreferences.edit();

            editor.putString("GG_LOGED", id_token);

            editor.commit();


【讨论】:

让我试试这个,然后我会回复你。 我想在登录时,然后下次打开应用程序时,它不会要求再次登录,而是显示下一个活动页面以显示其名称。你能帮我做吗? @RajKaran 你试试这个代码保存到 SharedPreferences: @RajKaran 刚刚更新了我上面的代码,所以你可以再试一次 查看我何时登录并获取所有详细信息,但是当我从内存中清除应用程序并再次启动应用程序时,它再次显示登录页面,我不想再次看到使用谷歌登录但我从登录中获得的所有详细信息。就像当你登录谷歌帐户并关闭它并清除内存时,你可以看到新闻提要而不是登录过程。【参考方案3】:

用户登录后,您可以使用此代码将数据存储在SharedPreference

SharedPreferences sharedPreferences = getSharedPreferences("APP", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("isLogin", true);
editor.putString("name", //Name);
editor.putString("e_mail",//Email);
editor.putString("ID", //ID);
editor.commit();

在启动画面中你可以这样做

boolean isLoggedIn = sharedPreferences.getBoolean("isLogin", false);

这里isLoggedIn是用户是否登录状态的值。您需要在 SplashScreen 中处理此问题并按此操作。

【讨论】:

我已经对其进行了编辑并添加了启动登录活动的启动活动代码,现在我很困惑将上面的代码放在哪里 我已经放了 boolean isLoggedIn = sharedPreferences.getBoolean("isLogin", false);" in finally but Where to put below code SharedPreferences sharedPreferences = getSharedPreferences("APP", MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean("isLogin", true); editor.putString("name", //Name); editor.putString( "e_mail",//Email); editor.putString("ID", //ID); editor.commit(); 在方法getSignInResult里面if条件。 editor.commit()的分号有问题; //显示错误 ')' 预期我已经放了括号但仍然错误 @RajKaran 将此代码 editor.putString("e_mail", editor.putString("ID", //ID); editor.putString("ID", //ID); 修改为 editor.putString("name", acct.getDisplayName()); editor.putString("e_mail", acct.getEmail()); editor.putString("ID", acct.getIdToken()); editor.commit();

以上是关于如何记住登录 Google 帐户 Android的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Authentication 从登录屏幕到登录屏幕使用 Google 登录和注销

如何让浏览器永久的自动记住我登录的账号

如何在JMeter中使用Google帐户登录

如何在使用 Google 登录按钮时不将 Google 帐户添加到 Android 手机

如何创建 Microsoft 帐户登录到我的网站,类似于 Google?

如何在 C# 中使用服务帐户登录 Google API - 凭据无效