如何使用谷歌活动结果API在一个点击登录



在我的一个Android应用程序中,我试图通过以下示例https://developers.google.com/identity/one-tap/android/get-saved-credentials#disable-one-tap包括一个点击登录身份验证。然而,在这里https://developer.android.com/reference/androidx/activity/ComponentActivity#startActivityForResult(android.content.Intent,int)它说函数startActivityForResult被弃用,而使用函数registerForActivityResult传递一个startActivityForResult对象为ActivityResultContract。在其他示例的帮助下,我可以编写以下代码

public class MainActivity extends AppCompatActivity {

private SignInClient oneTapClient;
private BeginSignInRequest signInRequest;
private ActivityResultLauncher<Intent> loginResultHandler = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
// handle intent result here
if (result.getResultCode() == RESULT_OK) {
SignInCredential credential = null;
try {
credential = oneTapClient.getSignInCredentialFromIntent(result.getData());
String idToken = credential.getGoogleIdToken();
String username = credential.getId();
String password = credential.getPassword();
if (idToken != null) {
// Got an ID token from Google. Use it to authenticate
// with your backend.
Log.d(TAG, "Got ID token.");
} else if (password != null) {
// Got a saved username and password. Use them to authenticate
// with your backend.
Log.d(TAG, "Got password.");
}
} catch (ApiException e) {
e.printStackTrace();
}
}
else {
//...
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
oneTapClient.beginSignIn(signInRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {
/*try {
android.app.Activity.startIntentSenderForResult(result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
}*/
loginResultHandler.launch(result.getPendingIntent().getIntentSender());
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No saved credentials found. Launch the One Tap sign-up flow, or
// do nothing and continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
}
}

只有我不能弄清楚如何转换指令loginResultHandler.launch(Result . getpendingintent ().getIntentSender())根据谷歌活动结果API (getIntentSender()返回一个但是loginResultHandler.launch()需要一个意图)。有人能帮助我或链接我工作的例子吗?谢谢你。

编辑:最后,我以以下方式重写了代码(我已经测试了它,直到帐户选择屏幕,它工作):

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private SignInClient oneTapClient;
private BeginSignInRequest signInRequest;
private boolean showOneTapUI = true;
private ActivityResultLauncher<IntentSenderRequest> loginResultHandler = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
// handle intent result here
if (result.getResultCode() == RESULT_OK) Log.d(TAG, "RESULT_OK.");
if (result.getResultCode() == RESULT_CANCELED) Log.d(TAG, "RESULT_CANCELED.");
if (result.getResultCode() == RESULT_FIRST_USER) Log.d(TAG, "RESULT_FIRST_USER.");
try {
SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(result.getData());
String idToken = credential.getGoogleIdToken();
String username = credential.getId();
String password = credential.getPassword();
if (idToken !=  null) {
// Got an ID token from Google. Use it to authenticate
// with your backend.
Log.d(TAG, "Got ID token.");
} else if (password != null) {
// Got a saved username and password. Use them to authenticate
// with your backend.
Log.d(TAG, "Got password.");
}
} catch (ApiException e) {
switch (e.getStatusCode()) {
case CommonStatusCodes.CANCELED:
Log.d(TAG, "One-tap dialog was closed.");
// Don't re-prompt the user.
showOneTapUI = false;
break;
case CommonStatusCodes.NETWORK_ERROR:
Log.d(TAG, "One-tap encountered a network error.");
// Try again or just ignore.
break;
default:
Log.d(TAG, "Couldn't get credential from result."
+ e.getLocalizedMessage());
break;
}
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
oneTapClient.beginSignIn(signInRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {
try {
loginResultHandler.launch(new IntentSenderRequest.Builder(result.getPendingIntent().getIntentSender()).build());
} catch(android.content.ActivityNotFoundException e){
e.printStackTrace();
Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No saved credentials found. Launch the One Tap sign-up flow, or
// do nothing and continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
}
}

您可以使用ActivityResultContracts.StartIntentSenderForResult类而不是ActivityResultContracts.StartActivityForResult

因此你可以重构你的代码像这样,

首先定义使用ActivityResultLauncher<IntentSenderRequest>实例而不是ActivityResultLauncher<Intent>实例给出结果时将做什么

private ActivityResultLauncher<IntentSenderRequest> loginResultHandler = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
// handle intent result here
if (result.getResultCode() == RESULT_OK) {
SignInCredential credential = null;
try {
credential = oneTapClient.getSignInCredentialFromIntent(result.getData());
String idToken = credential.getGoogleIdToken();
String username = credential.getId();
String password = credential.getPassword();
if (idToken != null) {
// Got an ID token from Google. Use it to authenticate
// with your backend.
Log.d(TAG, "Got ID token.");
} else if (password != null) {
// Got a saved username and password. Use them to authenticate
// with your backend.
Log.d(TAG, "Got password.");
}
} catch (ApiException e) {
e.printStackTrace();
}
}
else {
//...
}
});

现在在您的onCreate中,正如您在代码中提到的,您可以使用IntentSenderRequest.Builder类将您的IntentSender实例转换为IntentSenderRequest实例,该实例将被launch方法接受

oneTapClient.beginSignIn(signInRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {

try{
loginResultHandler.launch(new IntentSenderRequest.Builder(result.getPendingIntent().getIntentSender()).build());
}catch(IntentSenderException e){
e.printStackTrace()
}

}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No saved credentials found. Launch the One Tap sign-up flow, or
// do nothing and continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
}

请确保将其包装在try-catch结构中,并且应该是它。

在谷歌上搜索的时候偶然发现了这个答案,它可能对你也有帮助

或者,如果您愿意,这里有一个用Kotlin编写的类似解决方案:

从onCreate()方法启动登录流程

signInClient.beginSignIn(buildSignInRequest())
.addOnSuccessListener(this) { result ->
try {
signInResultHandler.launch(IntentSenderRequest.Builder(result.pendingIntent.intentSender).build())
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.message}")
}
}
.addOnFailureListener(this) { e ->
// TODO - No saved credentials found. Launch the One Tap sign-up flow, or do nothing and continue presenting the signed-out UI
Log.d(TAG, "No saved credentials found: ${e.message}")
}

并处理签到结果

private val signInResultHandler = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { activityResult: ActivityResult ->
when (activityResult.resultCode) {
RESULT_OK -> {
try {
val idToken = signInClient.getSignInCredentialFromIntent(activityResult.data).googleIdToken
when {
idToken != null -> {
// TODO - Got an ID token from Google. Use it to authenticate with Firebase
Log.d(TAG, "Got ID token.")
}
else -> {
Log.d(TAG, "No ID token!") // Shouldn't happen
}
}
} catch (e: ApiException) {
when (e.statusCode) {
CommonStatusCodes.CANCELED -> {
Log.d(TAG, "One-tap dialog was closed.")
showOneTapUI = false // Don't re-prompt the user
}
CommonStatusCodes.NETWORK_ERROR -> {
Log.d(TAG, "One-tap encountered a network error.")
// TODO - Try again or just ignore
}
else -> {
Log.d(TAG, "Couldn't get credential from result: ${e.message}")
}
}
}
}
}
}

相关内容

最新更新