我使用OAuth让用户通过Google帐户登录Android应用。当用户第一次点击Google登录按钮时,会生成一个用于选择帐户的对话框。同样,当用户退出并决定使用其他Google帐户登录时,它不会提示选择该帐户,而是会记录用户之前选择的帐户
'
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
initialize();
Firebase.setAndroidContext(this);
ref=new Firebase("https://texter10c.firebaseio.com");
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.setMessage("Logging in !");
progressDialog.setTitle("Hang on!");
progressDialog.show();
ref.authWithPassword(emailField.getText().toString(), passwordField.getText().toString(), new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(AuthData authData) {
Log.e("Authenticated","Authenticated");
getUserIdandLogin();
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, firebaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
signupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
startActivity(intent);
}
});
googleSignInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.setTitle("Contacting Google");
progressDialog.setMessage("Logging you in");
progressDialog.show();
if(!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
}
});
}
private void getGoogleToken(){
AsyncTask<Void,Void,String> task=new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
final String scopes="oauth2:"+"https://www.googleapis.com/auth/plus.login"+" "+"https://www.googleapis.com/auth/plus.me";
try {
if(!mGoogleApiClient.isConnected())
{
mGoogleApiClient.connect();
}
googleAccessToken= GoogleAuthUtil.getToken(LoginActivity.this,Plus.AccountApi.getAccountName(mGoogleApiClient),scopes);
Log.e("AccessToken",googleAccessToken+"");
}
catch (IOException e)
{
e.printStackTrace();
}
catch (GoogleAuthException e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
ref.authWithOAuthToken("google", googleAccessToken, new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(final AuthData authData) {
try {
Log.e("Firebase", "Google Authentication Success");
Log.e("Username", authData.getProviderData().get("displayName").toString());
Log.e("Id", authData.getProviderData().get("id").toString());
Firebase googleUserRef = ref.child("UserDetails/names/" + authData.getProviderData().get("id").toString());
Map<String, String> googleUserMap = new HashMap<String, String>();
googleUserMap.put("Username", authData.getProviderData().get("displayName").toString());
final String UserID = "GoogleUser" + authData.getProviderData().get("displayName") + authData.getProviderData().get("id");
googleUserMap.put("UserId", UserID);
googleUserRef.setValue(googleUserMap, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
progressDialog.dismiss();
dataStore.setCurrentUserName(authData.getProviderData().get("displayName").toString());
dataStore.setCurrentUserID(UserID);
storeDatainSharedPreferences();
Intent intent = new Intent(LoginActivity.this, DialogActivity.class);
startActivity(intent);
}
});
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {
Log.e("GogoleAuthFailed", firebaseError.getMessage());
}
});
}
catch (NullPointerException e)
{
Log.e("Accesstoken problem",e.getMessage());
}
}
};
task.execute();
}
public void getUserIdandLogin()
{
dataStore.userDialogMap=new ArrayList<Map<String,String>>();
dataStore.generatedChatIds=new ArrayList<>();
Firebase refUser=ref.child("UserDetails/names");
refUser.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, String> map = new HashMap<String, String>();
map = dataSnapshot.getValue(Map.class);
try{
if (map.get("Email").equals(emailField.getText().toString()))
{
Toast.makeText(LoginActivity.this, "Successfilly Logged in", Toast.LENGTH_SHORT).show();
dataStore.setCurrentUserName(map.get("Username"));
dataStore.setCurrentUserID(map.get("UserId"));
intent=new Intent(LoginActivity.this,DialogActivity.class);
startActivity(intent);
storeDatainSharedPreferences();
progressDialog.dismiss();
}
}
catch (NullPointerException e)
{
Log.e("NullPointerGUser",e.getMessage());
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
private void storeDatainSharedPreferences() {
try {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.putString("CurrentUsername", dataStore.getCurrentUserName());
editor.putString("CurrentUserId", dataStore.getCurrentUserID());
editor.commit();
}
catch (NoSuchElementException e)
{
new AlertDialog.Builder(LoginActivity.this).setMessage("There was an error whil logging in")
.setTitle("Little Problem here!").setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(LoginActivity.this,LoginActivity.class);
removeDatainSharedPreferences();
mGoogleApiClient.disconnect();
startActivity(intent);
}
}).show();
}
}
private void removeDatainSharedPreferences() {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.remove("CurrentUsername");
editor.remove("CurrentUserId");
editor.commit();
}
private void initialize() {
emailInputLayout=(TextInputLayout)findViewById(R.id.emailInputLayout);
emailField=(EditText)findViewById(R.id.emailField);
passwordField=(EditText)findViewById(R.id.passwordField);
passwordInputLayout=(TextInputLayout)findViewById(R.id.passwordInputLayout);
loginButton=(Button)findViewById(R.id.loginButton);
emailInputLayout.setHint("Email");
passwordInputLayout.setHint("Password");
progressDialog=new ProgressDialog(LoginActivity.this);
signupButton=(TextView)findViewById(R.id.signupButton);
forgotPasswordButton=(TextView)findViewById(R.id.forgotPasswordField);
googleSignInButton=(SignInButton)findViewById(R.id.googleSignInButton);
googleSignInButton.setColorScheme(SignInButton.COLOR_AUTO);
forgotPasswordButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(LoginActivity.this,ForgotPasswordActivity.class);
startActivity(intent);
}
});
SharedPreferences sharePreferences=getSharedPreferences(NEW_PREFS,MODE_PRIVATE);
if(!sharePreferences.getString("CurrentUsername","null").equals("null")) {
Log.e("SharedPreferences", sharePreferences.getString("CurrentUsername", "null"));
Log.e("SharedPreferences",sharePreferences.getString("CurrentUserId",null));
Intent intent=new Intent(LoginActivity.this,DialogActivity.class);
startActivity(intent);
}
mGoogleApiClient=new GoogleApiClient.Builder(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
if(!isNetworkAvailable())
{
snackbar=Snackbar.make(findViewById(android.R.id.content),"You are offline",Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!isNetworkAvailable())
dismissSnackBar();
else
snackbar.show();
}
});
snackbar.show();
}
}
private void dismissSnackBar() {
snackbar.dismiss();
}
private boolean isNetworkAvailable()
{
ConnectivityManager manager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkIngo=manager.getActiveNetworkInfo();
return networkIngo!=null&& networkIngo.isConnected();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.e("GoogleApi","Connected");
getGoogleToken();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e("GoogleApi",connectionResult.toString());
if(!connectionResult.hasResolution())
{
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(),LoginActivity.this,0).show();
}
if(connectionResult.isSuccess())
{
getGoogleToken();
}
try
{
connectionResult.startResolutionForResult(this,100);
}
catch (IntentSender.SendIntentException e)
{
e.printStackTrace();
}
}
}
`
只需在从意图中获取数据后添加此signIn()
方法。
Intent signInIntent=Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
mGoogleApiClient.clearDefaultAccountAndReconnect();
这对我有用。 !
@Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
}
mGoogleApiClient.stopAutoManage(Objects.requireNonNull(getActivity()));
mGoogleApiClient.disconnect();
}
如果要在Fragment或Activity中再次输入,则需要重新创建这些变量
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(Objects.requireNonNull(getActivity()))
.enableAutoManage(getActivity(), (this))
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
如果您有任何注销功能。将以下代码放在注销代码之前:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
}
else
{
CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(activity);
cookieSyncMngr.startSync();
CookieManager cookieManager=CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.removeSessionCookie();
cookieSyncMngr.stopSync();
cookieSyncMngr.sync();
}
希望这会有所帮助。
编辑:你也可以尝试用下面的代码替换你的
storeDatainSharedPreferences
方法:
private void storeDatainSharedPreferences() {
try {
SharedPreferences.Editor editor = getSharedPreferences(NEW_PREFS, MODE_PRIVATE).edit();
editor.putString("CurrentUsername", dataStore.getCurrentUserName());
editor.putString("CurrentUserId", dataStore.getCurrentUserID());
editor.commit();
if(mGoogleApiClient!=null)
mGoogleApiClient.disconnect();
}
catch (NoSuchElementException e)
{
new AlertDialog.Builder(LoginActivity.this).setMessage("There was an error whil logging in")
.setTitle("Little Problem here!").setPositiveButton("Retry", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(LoginActivity.this,LoginActivity.class);
removeDatainSharedPreferences();
mGoogleApiClient.disconnect();
startActivity(intent);
}
}).show();
}}
说明:对于第一个解决方案:清除与您的应用程序相关的所有Cookie的代码。这可能对您的情况有所帮助,因为您希望清除可能存储在Cookie中的先前数据。
说明:对于第二个解决方案:这是断开mGoogleApiClient的代码。这将是有帮助的,因为您已经将数据存储在sharedPref中,现在您不需要
mGoogleApiClient
。
最简单的方法是在处理结果后注销客户端(onActivityResult)。在触发注销之前,只需确保客户端已连接。这是我的代码片段:
private void handleGoogleLoginResult(Intent data) {
if (data != null) {
// get result from data received
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
int statusCode = result.getStatus().getStatusCode();
if (result.isSuccess() && result.getSignInAccount() != null) {
// Signed in successfully
}
// logout
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient);
}
}
}
只需为我锻炼
1> Activity implements GoogleApiClient.OnConnectionFailedListener {
2> mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
3>在OnButtonClicked中
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, 2);
4>
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
GoogleSignInAccount acct = result.getSignInAccount();
if(acct!=null) {
//Take all data You Want
String identifier = acct.getId()+"";
String displayName = acct.getDisplayName()+"";
//After You got your data add this to clear the priviously selected mail
mGoogleApiClient.clearDefaultAccountAndReconnect();
}
}else Log.e("handleSignInResult","Failed ; "+result.getStatus());
}
}
那些在kotlin中需要它的人,这对我有用,我会在新的登录请求发出之前清除当前的登录缓存
/**
* signInGoogle
*/
private fun signInGoogle() = launch{
//init google sigin
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(GOOGLE_WEBCLIENT_ID)
.requestEmail()
.build()
val gApiClient = GoogleApiClient.Builder(activity)
.addApi(Auth.GOOGLE_SIGN_IN_API,gso)
.build()
val c = gApiClient.blockingConnect()
if(c.isSuccess && gApiClient.isConnected){
gApiClient.clearDefaultAccountAndReconnect().await()
}
val mGoogleSignInClient = GoogleSignIn.getClient(activity, gso)
val signInIntent = mGoogleSignInClient.signInIntent
//start activit
startActivityForResult(signInIntent, GOOGLE_SIGNIN)
}//end request google login
您可以在这里查看完整的来源:https://github.com/transcodium/TNSMoney-Android/blob/master/app/src/main/java/com/transcodium/tnsmoney/SocialLoginActivity.kt
使用以下方式退出用户:
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
我在使用javascript客户端搜索解决方案时发现了这个问题,但它可能与Android类似。
signIn({ prompt: 'select_account' })
select_account
授权服务器提示用户选择Google帐户。这允许具有多个帐户的用户在多个帐户中选择他们可能具有当前会话的帐户。
见https://developers.google.com/identity/sign-in/web/reference#googleauthsigninoptions。
您没有通过注销来撤销用户使用以下内容来实现您的需求:
将此代码放入任何活动中并在注销按钮单击中调用它:
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
// ...
}
});
}
在onCreate()
写这个:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
在onStart()
中覆盖它:
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
您需要从谷歌客户端注销用户
public void signOut() {
mAuth.signOut();
mGoogleSignInClient.signOut();
LoginManager.getInstance().logOut();
}
哪里
private FirebaseAuth mAuth;
private GoogleSignInClient mGoogleSignInClient;
和
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
mAuth = FirebaseAuth.getInstance();
我正在使用Firebase Auth UI,对我而言,修复是;
AuthUI.getInstance().setIsSmartLockEnabled(false)...
登录时,然后;
AuthUI.signOut(context)
注销时