smart3d加载到谷歌_Android Google Smart Lock

裴嘉良
2023-12-01

smart3d加载到谷歌

In this tutorial, we’ll be discussing the Smart Lock feature and implement it in our Android Application.

在本教程中,我们将讨论Smart Lock功能,并将其在我们的Android应用程序中实现。

Google Smart Lock (Google Smart Lock)

Smart Lock is used to automatically sign into your application by saving the credentials once and for all.
That means that if you reinstall your application after a while, you can automatically sign in with the previously saved credentials provided you didn’t delete them from the chrome passwords.

Smart Lock用于通过一劳永逸地保存凭据自动登录您的应用程序。
这意味着,如果过一会儿重新安装应用程序,只要您没有从Chrome密码中删除它们,就可以使用以前保存的凭据自动登录。

Google Smart Lock lets you sign in with just one tap.
Google Smart Lock可让您一键登录。

In order to integrate Smart Lock in your application, you need to use Credentials API.

为了将Smart Lock集成到您的应用程序中,您需要使用凭据API。

Credentials API allow the user to:

凭据API允许用户:

  • Request credentials when opening the app.

    打开应用程序时请求凭据。
  • Save credentials from the login form.

    保存登录表单中的凭据。
  • Sync credentials between the app and website.

    在应用程序和网站之间同步凭据。
  • Display email hints in case we want to help the user in the sign-in/sign-up process.

    如果希望在登录/注册过程中帮助用户,请显示电子邮件提示。

To use Google Smart Lock in your application you need to add the following dependency:

要在您的应用程序中使用Google Smart Lock,您需要添加以下依赖项:

dependencies {
    implementation 'com.google.android.gms:play-services-auth:16.0.0'
}

SmartLock requires the GoogleApiClient to be setup in your android application.

SmartLock要求在您的android应用程序中设置GoogleApiClient。

SmartLock allows auto-sign in when there is only one credential.

只有一个凭证时,SmartLock允许自动登录。

When there are more than one credentials, they are shown up in a dialog.

如果凭证不止一个,它们将显示在一个对话框中。


Now with Google Smart Lock everything is taken care of by the Google Servers.
现在,借助Google Smart Lock,Google服务器可以处理一切。

Following are the major methods present in the Credentials API:

以下是凭据API中存在的主要方法:

  • save(GoogleApiClient client, Credential credential)

    save(GoogleApiClient client, Credential credential)
  • request(GoogleApiClient client, CredentialRequestrequest) - Requests all the credentials saved for the app.

    request(GoogleApiClient client, CredentialRequestrequest) -请求为应用程序保存的所有凭据。
  • getHintPickerIntent(GoogleApiClient client, HintRequest request) - Shows a list of signed-in accounts you have in order to quickly fill up login forms.

    getHintPickerIntent(GoogleApiClient client, HintRequest request) -显示您具有的登录帐户列表,以便快速填写登录表单。
  • disableAutoSignIn(GoogleApiClient client)

    disableAutoSignIn(GoogleApiClient client)
  • delete(GoogleApiClient client, Credential credential)

    delete(GoogleApiClient client, Credential credential)

You can view all the credentials saved for a Google account by going to passwords.google.com.

您可以转到passwords.google.com来查看为Google帐户保存的所有凭据。

What’s the Flow for an application with Smart Lock?

使用Smart Lock的应用程序的流程是什么?

You need to structure your login screen code in the following way:

您需要通过以下方式来构造登录屏幕代码:

  • Check for Credentials. If a single credential exists, auto-sign or auto-fill the login form.

    检查凭据。 如果存在单个凭据,请自动签名或自动填写登录表单。
  • If there are more than one credentials, show them in a dialog and let the user choose.

    如果有多个凭据,请在对话框中显示它们,然后让用户选择。
  • If there are no saved credentials you can either let the user fill up the form OR make it easier for them by AutoFill or showing a Hint dialog with available accounts to sign in with.

    如果没有保存的凭据,则可以让用户填写表单,也可以通过自动填充使它们变得更容易,也可以显示一个提示对话框,其中包含可用的帐户进行登录。

入门 (Getting Started)

Let’s begin our implementation of Smart Lock feature in an Android application.

让我们开始在Android应用程序中实现Smart Lock功能。

Set up GoogleApiClient

设置GoogleApiClient

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(Auth.CREDENTIALS_API)
                .enableAutoManage(this, this)
                .build();

Implement the GoogleApiClient interfaces and implement the methods.

实现GoogleApiClient接口并实现方法。

Initialise Credentials Client

初始化凭据客户端

CredentialsOptions options = new CredentialsOptions.Builder()
                .forceEnableSaveDialog()
                .build();


CredentialsClient  mCredentialsApiClient = Credentials.getClient(this, options);

forceEnableSaveDialog() is required for Android Oreo and above.

Android Oreo及更高版本需要forceEnableSaveDialog()

Create CredentialRequest

创建凭据请求

CredentialRequest mCredentialRequest = new CredentialRequest.Builder()
                .setPasswordLoginSupported(true)
                .setAccountTypes(IdentityProviders.GOOGLE)
                .build();

Retrieve Credentials

检索凭证

Auth.CredentialsApi.request(mGoogleApiClient, mCredentialRequest).setResultCallback(this);

The setResultCallBack requires us to override the method onResult from the interface ResultCallback<CredentialRequestResult>

setResultCallBack要求我们从ResultCallback<CredentialRequestResult>接口重写onResult方法onResult

@Override
    public void onResult(@NonNull CredentialRequestResult credentialRequestResult) {

        Status status = credentialRequestResult.getStatus();
        if (status.isSuccess()) {
            onCredentialRetrieved(credentialRequestResult.getCredential());
        } else {
            if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
                try {
                    isResolving = true;
                    status.startResolutionForResult(this, RC_READ);
                } catch (IntentSender.SendIntentException e) {
                    Log.d(TAG, e.toString());
                }
            } else {

                showHintDialog();
            }
        }
    }

There are three cases –

有三种情况–

  • Multiple Credentials – Resolve them and display all the available credentials in a dialog

    多个凭据–解决它们并在对话框中显示所有可用的凭据
  • No Credentials – Show a Hint Dialog with all the available sign in accounts

    没有凭据–显示提示对话框,其中包含所有可用的登录帐户

A status code of RESOLUTION_REQUIRED implies that there are more than one credentials that need to be resolved. For this, we call startResolutionForResult which returns the result in the onActivityResult method.

状态代码为RESOLUTION_REQUIRED表示有多个凭据需要解析。 为此,我们调用startResolutionForResult ,它在onActivityResult方法中返回结果。

We use a boolean flag in order to prevent multiple resolutions to occur. That would cause multiple dialogs to be built.

我们使用布尔标志以防止出现多种分辨率。 这将导致建立多个对话框。

Now that we’ve seen the gist of the SmartLock feature, lets implement it fully with saving and deleting credentials features.

现在,我们已经了解了SmartLock功能的要点,让我们通过保存和删除凭据功能来完全实现它。

项目结构 (Project Structure)

(Code)

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:importantForAutofill="noExcludeDescendants">


    <Button
        android:id="@+id/btnLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="24dp"
        android:text="Login"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inPassword" />

    <EditText
        android:id="@+id/inEmail"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="32dp"
        android:ems="10"
        android:hint="email"
        android:inputType="textEmailAddress"
        app:layout_constraintHorizontal_bias="0.503"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <EditText
        android:id="@+id/inPassword"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="8dp"
        android:ems="10"
        android:hint="password"
        android:inputType="textPassword"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inEmail" />


</android.support.constraint.ConstraintLayout>

android:importantForAutofill="noExcludeDescendants"> is used to disable Autofill on the EditText Fields.
We’ll discuss the Autofill API in a separate tutorial.

android:importantForAutofill="noExcludeDescendants">用于在EditText字段上禁用自动填充。
我们将在单独的教程中讨论Autofill API。

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidgooglesmartlock;

import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentSender;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialPickerConfig;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResponse;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.Credentials;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
import com.google.android.gms.auth.api.credentials.HintRequest;
import com.google.android.gms.auth.api.credentials.IdentityProviders;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<CredentialRequestResult> {

    private GoogleApiClient mGoogleApiClient;
    CredentialsClient mCredentialsApiClient;
    CredentialRequest mCredentialRequest;
    public static final String TAG = "API123";
    private static final int RC_READ = 3;
    private static final int RC_SAVE = 1;
    private static final int RC_HINT = 2;
    boolean isResolving;

    Button btnLogin;
    EditText inEmail, inPassword;

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

        setUpGoogleApiClient();

        //needed for Android Oreo.
        CredentialsOptions options = new CredentialsOptions.Builder()
                .forceEnableSaveDialog()
                .build();


        mCredentialsApiClient = Credentials.getClient(this, options);
        createCredentialRequest();

        btnLogin = findViewById(R.id.btnLogin);
        inEmail = findViewById(R.id.inEmail);
        inPassword = findViewById(R.id.inPassword);

        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String email = inEmail.getText().toString();
                String password = inPassword.getText().toString();
                if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password) || !Patterns.EMAIL_ADDRESS.matcher(email).matches())
                    showToast("Please enter valid email and password");

                else {

                    Credential credential = new Credential.Builder(email)
                            .setPassword(password)
                            .build();

                    saveCredentials(credential);
                }

            }
        });
    }

    public void setUpGoogleApiClient() {


        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(Auth.CREDENTIALS_API)
                .enableAutoManage(this, this)
                .build();
    }

    public void createCredentialRequest() {
        mCredentialRequest = new CredentialRequest.Builder()
                .setPasswordLoginSupported(true)
                .setAccountTypes(IdentityProviders.GOOGLE)
                .build();
    }

    public void requestCredentials() {
        Auth.CredentialsApi.request(mGoogleApiClient, mCredentialRequest).setResultCallback(this);
    }


    private void onCredentialRetrieved(Credential credential) {
        String accountType = credential.getAccountType();
        if (accountType == null) {
            // Sign the user in with information from the Credential.
            gotoNext();
        } else if (accountType.equals(IdentityProviders.GOOGLE)) {


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

            GoogleSignInClient signInClient = GoogleSignIn.getClient(this, gso);
            Task<GoogleSignInAccount> task = signInClient.silentSignIn();

            task.addOnCompleteListener(new OnCompleteListener<GoogleSignInAccount>() {
                @Override
                public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
                    if (task.isSuccessful()) {
                        // See "Handle successful credential requests"
                        populateLoginFields(task.getResult().getEmail(), null);
                    } else {
                        showToast("Unable to do a google sign in");
                    }
                }
            });
        }
    }


    public void gotoNext() {
        startActivity(new Intent(this, SecondActivity.class));
        finish();
    }


    public void showToast(String s) {
        Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d("API123", "onConnected");
        requestCredentials();

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    protected void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    @Override
    public void onResult(@NonNull CredentialRequestResult credentialRequestResult) {

        Status status = credentialRequestResult.getStatus();
        if (status.isSuccess()) {
            onCredentialRetrieved(credentialRequestResult.getCredential());
        } else {
            if (status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
                try {
                    isResolving = true;
                    status.startResolutionForResult(this, RC_READ);
                } catch (IntentSender.SendIntentException e) {
                    Log.d(TAG, e.toString());
                }
            } else {

                showHintDialog();
            }
        }
    }

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

        Log.d(TAG, "onActivityResult");
        if (requestCode == RC_READ) {
            if (resultCode == RESULT_OK) {
                Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
                onCredentialRetrieved(credential);
            } else {
                Log.d(TAG, "Request failed");
            }
            isResolving = false;
        }

        if (requestCode == RC_HINT) {
            if (resultCode == RESULT_OK) {
                Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
                populateLoginFields(credential.getId(), "");
            } else {
                showToast("Hint dialog closed");
            }
        }

        if (requestCode == RC_SAVE) {
            if (resultCode == RESULT_OK) {
                Log.d(TAG, "SAVE: OK");
                gotoNext();
                showToast("Credentials saved");
            }
        }


    }

    public void populateLoginFields(String email, String password) {
        if (!TextUtils.isEmpty(email))
            inEmail.setText(email);

        if (!TextUtils.isEmpty(password))
            inPassword.setText(password);
    }

    public void showHintDialog() {
        HintRequest hintRequest = new HintRequest.Builder()
                .setHintPickerConfig(new CredentialPickerConfig.Builder()
                        .setShowCancelButton(true)
                        .build())
                .setEmailAddressIdentifierSupported(true)
                .setAccountTypes(IdentityProviders.GOOGLE)
                .build();

        PendingIntent intent = mCredentialsApiClient.getHintPickerIntent(hintRequest);
        try {
            startIntentSenderForResult(intent.getIntentSender(), RC_HINT, null, 0, 0, 0);
        } catch (IntentSender.SendIntentException e) {
            Log.e(TAG, "Could not start hint picker Intent", e);
        }
    }

    public void saveCredentials(Credential credential) {


        mCredentialsApiClient.save(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "SAVE: OK");
                    showToast("Credentials saved");
                    return;
                }

                Exception e = task.getException();
                if (e instanceof ResolvableApiException) {
                    // Try to resolve the save request. This will prompt the user if
                    // the credential is new.
                    ResolvableApiException rae = (ResolvableApiException) e;
                    try {
                        rae.startResolutionForResult(MainActivity.this, RC_SAVE);
                    } catch (IntentSender.SendIntentException f) {
                        // Could not resolve the request
                        Log.e(TAG, "Failed to send resolution.", f);
                        showToast("Saved failed");
                    }
                } else {
                    // Request has no resolution
                    showToast("Saved failed");
                }
            }
        });

    }
}

In the onConnected method we request for available credentials.
That means as soon as the activity is started the credentials if any are retrieved.
If a single credential is there, then it would auto sign and goto the next activity.

在onConnected方法中,我们请求可用的凭据。
这意味着,一旦开始活动,便会检索凭证(如果有的话)。
如果存在单个凭证,则它将自动签名并转到下一个活动。

The code for the activity_second.xml layout is given below:

下面给出了activity_second.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <Button
        android:id="@+id/btnDeleteAccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Delete account"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnSignOut" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="You are logged in."
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnSignOut"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="SIGN OUT"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/btnSignOutDisableAutoSign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SIGN OUT AND DISABLE AUTO SIGN IN"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnDeleteAccount" />
</android.support.constraint.ConstraintLayout>

Inside the SecondActivity, we’ll do three different actions – Sign out, Sign out and disable auto-sign in the next time, delete credential.

在SecondActivity内部,我们将执行三种不同的操作-注销,注销并在下次禁用自动登录,删除凭据。

The code for the SecondActivity.java class is given below:

SecondActivity.java类的代码如下:

package com.journaldev.androidgooglesmartlock;

import android.content.Intent;
import android.content.IntentSender;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
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.Toast;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.Credentials;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;

public class SecondActivity extends AppCompatActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<CredentialRequestResult> {


    Button btnSignOut, btnSignOutDisableAuto, btnDelete;
    private GoogleApiClient mGoogleApiClient;
    CredentialsClient mCredentialsApiClient;
    CredentialRequest mCredentialRequest;
    public static final String TAG = "API123";
    private static final int RC_REQUEST = 4;


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

        setUpGoogleApiClient();
        mCredentialsApiClient = Credentials.getClient(this);


        btnSignOut = findViewById(R.id.btnSignOut);
        btnSignOutDisableAuto = findViewById(R.id.btnSignOutDisableAutoSign);
        btnDelete = findViewById(R.id.btnDeleteAccount);

        btnSignOut.setOnClickListener(this);
        btnSignOutDisableAuto.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnSignOut:
                signOut(false);
                break;
            case R.id.btnSignOutDisableAutoSign:
                signOut(true);
                break;
            case R.id.btnDeleteAccount:
                requestCredentials();

                break;
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onResult(@NonNull CredentialRequestResult credentialRequestResult) {

        Status status = credentialRequestResult.getStatus();
        if (status.isSuccess()) {
            onCredentialSuccess(credentialRequestResult.getCredential());
        } else {
            if (status.hasResolution()) {
                try {
                    status.startResolutionForResult(this, RC_REQUEST);
                } catch (IntentSender.SendIntentException e) {
                    Log.d(TAG, e.toString());
                }
            } else {
                showToast("Request Failed");
            }
        }
    }

    public void setUpGoogleApiClient() {

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(Auth.CREDENTIALS_API)
                .enableAutoManage(this, this)
                .build();
    }


    private void requestCredentials() {
        mCredentialRequest = new CredentialRequest.Builder()
                .setPasswordLoginSupported(true)
                .build();

        Auth.CredentialsApi.request(mGoogleApiClient, mCredentialRequest).setResultCallback(this);
    }


    @Override
    protected void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    private void onCredentialSuccess(Credential credential) {

        Auth.CredentialsApi.delete(mGoogleApiClient, credential).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(@NonNull Status status) {
                if (status.isSuccess()) {
                    signOut(false);
                } else {
                    showToast("Account Deletion Failed");
                }
            }
        });


    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RC_REQUEST) {
            if (resultCode == RESULT_OK) {
                showToast("Deleted");
                Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
                onCredentialSuccess(credential);
            } else {
                Log.d(TAG, "Request failed");
            }
        }
    }

    public void showToast(String s) {
        Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
    }

    private void signOut(boolean disableAutoSignIn) {

        if (disableAutoSignIn)
            Auth.CredentialsApi.disableAutoSignIn(mGoogleApiClient);

        startActivity(new Intent(this, MainActivity.class));
        finish();
    }
}

The output of the above application in action is given below:

上面应用程序的输出如下:

We created the first account and see that everytime you open the app, it automatically signs in.
Unless we disable auto-sign. Then it will ask for permission before signing in.
We created another account. This time when we delete it. And the application auto-signs into the first account after deletion.

我们创建了第一个帐户,并看到每次打开该应用程序时,该帐户都会自动登录。
除非我们禁用自动签名。 然后它将在登录之前征求许可。
我们创建了另一个帐户。 这次我们删除它。 删除后,应用程序自动登录到第一个帐户。

That brings an end to this tutorial. You can download the project from the link below:

这样就结束了本教程。 您可以从下面的链接下载项目:

翻译自: https://www.journaldev.com/23287/android-google-smart-lock

smart3d加载到谷歌

 类似资料: