OnActivityResult not called after startIntentSenderForResult - android

I'm using a launch page to "Sign in with Google". When the user has multiple accounts...after they select which account they wish to sign in with, I'm trying to launch the apps main activity, but for some reason the onActivityResult is never called in my fragment.
Im the Activity, I call onActivityResult and let it call super so that the fragment can handle it, but it never fires.
Any suggestions?
Here is the fragment that is in question:
package com.garciaericn.goodeats.login;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.garciaericn.goodeats.R;
import com.garciaericn.goodeats.helpers.CheckConnection;
import com.garciaericn.goodeats.main.FavoritesActivity;
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.plus.Plus;
public class LoginFragment extends Fragment implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = "com.garciaericn.goodeats.login.LoginFragment.TAG";
/* Request code used to invoke sign in user interactions. */
private static final int RC_SIGN_IN = 0;
private static final int RC_LOGGED_IN = 1034553;
public static final int RC_SIGN_OUT = 34458392;
/* 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;
/* Store the connection result from onConnectionFailed callbacks so that we can
* resolve them when the user clicks sign-in.
*/
private ConnectionResult mConnectionResult;
private boolean mSignInClicked;
private boolean mSignedIn;
private CheckConnection checkConnection;
public LoginFragment() {
}
public static LoginFragment getInstance() {
return new LoginFragment();
}
private void signOut() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
mIntentInProgress = false;
mSignInClicked = false;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkConnection = new CheckConnection(getActivity());
setHasOptionsMenu(true);
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login, container, false);
SignInButton signInButton = (SignInButton) view.findViewById(R.id.g_plus_login);
signInButton.setSize(SignInButton.SIZE_WIDE);
signInButton.setOnClickListener(this);
return view;
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_sign_out:
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
checkConnection.isConnected();
switch (v.getId()) {
case R.id.g_plus_login:
if (!mGoogleApiClient.isConnected()) {
mSignInClicked = true;
resolveSignInError();
}
break;
default:
// If default action is needed.
break;
}
}
#Override
public void onConnected(Bundle bundle) {
mSignInClicked = false;
mSignedIn = true;
// User is connected
String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
Toast.makeText(getActivity(), accountName, Toast.LENGTH_SHORT).show();
// String accountID = GoogleAuthUtil.getAccountId(getActivity(), accountName);
// try {
// accountID = GoogleAuthUtil.getAccountId(getActivity().getApplicationContext(),accountName);
// } catch (GoogleAuthException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
// if (accountID != null) {
// // TODO: createLocalAccount() = Store account name and id with DB of restaurants
// }
// Launch main activity
Intent intent = new Intent(getActivity(), FavoritesActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (!mIntentInProgress) {
// Store the ConnectionResult so that we can use it later when the user clicks
// 'sign-in'.
mConnectionResult = connectionResult;
if (mSignInClicked) {
resolveSignInError();
}
}
checkConnection.isConnected();
// if (!checkConnection.isConnected()) {
// Toast.makeText(getActivity(), "No network connection", Toast.LENGTH_SHORT).show();
// }
}
public void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
getActivity().startIntentSenderForResult(mConnectionResult.getResolution().getIntentSender(), RC_SIGN_IN, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
// The intent was canceled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult.
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
if (resultCode != Activity.RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
} else if (requestCode == RC_LOGGED_IN) {
if (resultCode == RC_SIGN_OUT) {
signOut();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}

The key was to call the below method in the first activity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}

Add this in your outer Activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.change_to_your_id);
fragment.onActivityResult(requestCode, resultCode, data);
}

To properly solve this problem You might use already prepared solution accountPicker.
However - If You want to devise Your own solution - one idea is to start Your second activity (from first activity obviously) with:
Intent intent = this.getIntent();
intent.putExtra(... /* some code that will control second activity */
startActivityForResult(intent, request_code);
and then when activity did all it had to do You allow it to return:
Intent intent = this.getIntent();
intent.putExtra(... /* all needed results to return */ );
this.setResult(RESULT_OK, intent);
finish();
finally it is Your first activity that then gets result in its onActivityResult.

Related

How to revoke google account access within my android app?

I am new to android and would like to know how to revoke access of someone who has signed-in to my app using GoogleSignInApi.
I want my app to ask for the user's google account id when user revokes the access within the app. Currently my app automatically signs-in once the user clicks on SignIn button, even after the user has clicked revoke access button.
I am broadcasting an intent when the user clicks on revoke or sign out button of my app. Below is the code for my MainActivity.
public class MasterActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = MasterActivity.class.getSimpleName();
private SharedPreferences sp;
private SharedPreferences.Editor editor;
private BroadcastReceiver mSignOutReceiver;
private IntentFilter mSignOutFilter;
private IntentFilter mRevokeAccessFilter;
private BroadcastReceiver mRevokeAccessReceiver;
private String mUserName;
private String mPhotoUrl;
private String mEmailId;
private static final String ANONYMOUS = "anonymous";
private ImageView profileImageView;
private TextView profileDisplayName, profileEmailId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// [START Check for sign out broadcast.]
mSignOutFilter = new IntentFilter();
mSignOutFilter.addAction(getString(R.string.action_signout));
mSignOutReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Sign Out in progress.");
Intent signinIntent = new Intent(getApplicationContext(), SigninActivity.class);
startActivity(signinIntent);
finish();
}
};
this.registerReceiver(mSignOutReceiver, mSignOutFilter);
// [END Check for sign out broadcast.]
mRevokeAccessFilter = new IntentFilter();
mRevokeAccessFilter.addAction(getString(R.string.action_revoke));
mRevokeAccessReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Revoke access in progress.");
Intent revokeIntent = new Intent(getApplicationContext(), SigninActivity.class);
startActivity(revokeIntent);
finish();
}
};
this.registerReceiver(mRevokeAccessReceiver, mRevokeAccessFilter);
setContentView(R.layout.activity_master);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/* FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});*/
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
sp = getSharedPreferences(getString(R.string.user_cred_sp),MODE_PRIVATE);
editor = sp.edit();
if(!sp.contains("USER_ID")){
//Not signed in, launch the Sign In activity
Log.d(TAG, "User id not is present.");
startActivity(new Intent(this, SigninActivity.class));
finish();
return;
} else {
// [START Set the navigation header details]
mUserName = sp.getString("USER_DISPLAY_NAME",ANONYMOUS);
mPhotoUrl = sp.getString("USER_PIC_URL",null);
mEmailId = sp.getString("USER_EMAIL","noemailid#unknown.com");
View headerView = navigationView.inflateHeaderView(R.layout.nav_header_master);
profileDisplayName = (TextView) headerView.findViewById(R.id.UserNameProfile);
profileDisplayName.setText(mUserName);
profileEmailId = (TextView) headerView.findViewById(R.id.EmailIdProfile);
profileEmailId.setText(mEmailId);
profileImageView = (ImageView) headerView.findViewById(R.id.ImageViewProfile);
if(mPhotoUrl!=null){
Glide.with(getApplicationContext()).load(mPhotoUrl)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(profileImageView);
}
//TODO: The orientation of views and image is not proper
// [END Set the navigation header details]
}
}
/*#Override
protected void onResume(){
super.onResume();
this.registerReceiver(mSignOutReceiver, signOutFilter);
}*/
#Override
protected void onDestroy(){
super.onDestroy();
this.unregisterReceiver(mSignOutReceiver);
this.unregisterReceiver(mRevokeAccessReceiver);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.master, 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;
} else if (id == R.id.sign_out_menu ){
signOutBroadCast();
return true;
} else if (id == R.id.revoke_menu){
revokeAccessBroadCast();
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_logout) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private void signOutBroadCast(){
// 1. Clear the shared preference.
editor.clear();
editor.apply();
// 2.Send a sign out broadcast
Intent signOutIntent = new Intent();
signOutIntent.setAction(getString(R.string.action_signout));
sendBroadcast(signOutIntent);
// 3. Start the login Activity
/*Intent signinIntent = new Intent(this,SigninActivity.class);
startActivity(signinIntent);
finish();*/
}
private void revokeAccessBroadCast(){
// 1. Clear the shared preference.
editor.clear();
editor.apply();
// 2.Send a revoke intent.
Intent revokeIntent = new Intent();
revokeIntent.setAction(getString(R.string.action_revoke));
sendBroadcast(revokeIntent);
//signOutBroadCast();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed: "+ connectionResult);
}
}
This is my code for SignInActivity.
public class SigninActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener,
GoogleApiClient.ConnectionCallbacks{
private static final String TAG = SigninActivity.class.getSimpleName();
private static final int REQ_ACCPICK = 1;
private static final int RC_SIGN_IN = 2;
private GoogleSignInOptions mGoogleSignInOptions;
private GoogleApiClient mGoogleApiClient;
private SharedPreferences sp;
private SharedPreferences.Editor editor;
private IntentFilter mSignOutFilter;
private BroadcastReceiver mSignOutReceiver;
private IntentFilter mRevokeAccessFilter;
private BroadcastReceiver mRevokeAccessReceiver;
private boolean isAccntConnected;
private SignInButton btnSignIn;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSignOutFilter = new IntentFilter();
mSignOutFilter.addAction(getString(R.string.action_signout));
mSignOutReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
signOutIfConnected();
Log.d(TAG, "Sign out complete.");
}
};
this.registerReceiver(mSignOutReceiver, mSignOutFilter);
mRevokeAccessFilter = new IntentFilter();
mRevokeAccessFilter.addAction(getString(R.string.action_revoke));
mRevokeAccessReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"Revoke access");
revokeAccess();
Log.d(TAG, "Complete access revoked.");
}
};
this.registerReceiver(mRevokeAccessReceiver, mRevokeAccessFilter);
// [START Sign out if connected.]
//signOutIfConnected();
// [END Sign out if connected.]
setContentView(R.layout.activity_signin);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignIn.setOnClickListener(this);
// [START Configure sign in]
// configure sign in options for google account
mGoogleSignInOptions= new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
// [END Configure sign in]
isAccntConnected= false;
// [START Build Google api client]
/*mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();*/
// [END Build Google api client]
btnSignIn.setSize(SignInButton.SIZE_STANDARD);
btnSignIn.setScopes(mGoogleSignInOptions.getScopeArray());
sp = getSharedPreferences(getString(R.string.user_cred_sp), MODE_PRIVATE);
editor = sp.edit();
}
/*#Override
protected void onResume(){
super.onResume();
this.registerReceiver(mSignOutReceiver, mSignOutFilter);
this.registerReceiver(mRevokeAccessReceiver, mRevokeAccessFilter);
}*/
/*#Override
protected void onPause(){
super.onPause();
this.unregisterReceiver(mSignOutReceiver);
this.unregisterReceiver(mRevokeAccessReceiver);
}*/
#Override
protected void onDestroy(){
super.onDestroy();
this.unregisterReceiver(mSignOutReceiver);
this.unregisterReceiver(mRevokeAccessReceiver);
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed: " + connectionResult);
}
private void initGAC(){
/*mGoogleSignInOptions= new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.setAccountName(acntName)
.build();*/
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, mGoogleSignInOptions)
//.setAccountName(acntName)
.build();
}
#Override
public void onStart() {
super.onStart();
if(mGoogleApiClient!=null){
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone()) {
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Log.d(TAG, "Got cached sign in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
} else {
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
showProgressDialog();
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
#Override
public void onResult(GoogleSignInResult googleSignInResult) {
hideProgressDialog();
handleSignInResult(googleSignInResult);
}
});
}
}
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_sign_in) {
signIn();
}
}
private void signIn() {
/*startActivityForResult(AccountPicker.newChooseAccountIntent(
null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null
),REQ_ACCPICK);*/
Log.d(TAG, "Sign in method called.");
initGAC();
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/*if(requestCode == REQ_ACCPICK){
if(data!=null && data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)!=null){
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
initGAC(mEmail);
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
} else*/
if (requestCode == RC_SIGN_IN) {
Log.d(TAG, "Sign in request");
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Sign in successful. Show authenticated UI
// Set the data in intent and send it to next activity
GoogleSignInAccount acct = result.getSignInAccount();
Log.d(TAG, "Account Profile URL: "+acct.getPhotoUrl().toString());
String userId = acct.getId();
String userDisplayName = acct.getDisplayName();
String userPhotoUrl = acct.getPhotoUrl().toString();
String userEmail = acct.getEmail();
//Set the id in shared preferences so that it can be used to log out
editor.putString("USER_ID", userId);
editor.putString("USER_DISPLAY_NAME", userDisplayName);
editor.putString("USER_PIC_URL", userPhotoUrl);
editor.putString("USER_EMAIL", userEmail);
editor.commit();
//dataIntent.putExtra("USER_EMAIL",userEmail);
Intent dataIntent = new Intent(this, MasterActivity.class);
startActivity(dataIntent);
}
}
private void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(getString(R.string.loading));
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
private void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.hide();
}
}
private void signOutIfConnected() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
//mEmail=null;
mGoogleApiClient.clearDefaultAccountAndReconnect();
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.d(TAG, "Sign Out using Google Api.");
mGoogleApiClient.disconnect();
isAccntConnected = false;
}
});
}
}
private void revokeAccess(){
if (mGoogleApiClient != null && mGoogleApiClient.isConnected() && isAccntConnected == true) {
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.d(TAG, "Revoke access using Google Api.");
signOutIfConnected();
}
});
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
this.isAccntConnected = true;
}
#Override
public void onConnectionSuspended(int i) {
}
/*#Override
public void onConnected(#Nullable Bundle bundle) {
if(!sp.contains("USER_ID_TOKEN")){
signOut();
}
}
#Override
public void onConnectionSuspended(int i) {
}*/
}
I may be missing something or may be doing something wrong. Please guide me.
After spending two days, trying to understand Android activity life cycle, I was able to figure out the solution to this problem. There were two major flaws in the code above.
I had not registered the callbacks in GoogleApiClient. Due to this code was not flowing inside onConnected(), onConnectionSuspended() and onConnectionFailed(). Solution is to register them as shown below:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Auth.GOOGLE_SIGN_IN_API, mGoogleSignInOptions)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
I had enabled auto mangement of GoogleApiClient as shown in this link https://developers.google.com/identity/sign-in/android/. Though this is not a flaw, right now I am unable to use it for my benefit.
It automatically connects GoogleApiClient instance when onStart is called and disconnects it when onStop is called. So when a user logs in to my app, the app takes her to MasterActivity. Along the way, onStop method of SignInActivity is called. This disconnected GoogleApiClient instance (remember automanaged ). So the solution was to manage it myself within my code.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN && resultCode == RESULT_OK) {
Log.d(TAG, "Sign in request");
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
mGoogleApiClient.connect();//CALL TO CONNECT GoogleApiClient
handleSignInResult(result);
}
}
private void signOutIfConnected() {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.clearDefaultAccountAndReconnect();
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.d(TAG, "Sign Out using Google Api.");
mGoogleApiClient.disconnect();
//CALL TO DISCONNECT GoogleApiClient
isAccntConnected = false;
}
});
}
}
private void revokeAccess(){
if (isAccntConnected == true) {
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.d(TAG, "Revoke access using Google Api.");
//signOutIfConnected(); //REMOVED
}
});
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
isAccntConnected = true;
}
I also introduced a boolean flag isAccntConnected to ensure that call to onConnected method has been made before invoking revokeAccess method as suggested here https://developers.google.com/identity/sign-in/android/disconnect. i.e.
You must confirm that GoogleApiClient.onConnected has been called before you call revokeAccess.
After these changes, my app works as it was meant to be. The code to revoke access remains the same, except that I have removed nested call to signOutIfConnected method inside its onResult method.
Hope this answer will help lots of beginners like me.
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
}
});
}
private void revokeAccess() {
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
}
});
}
https://developers.google.com/identity/sign-in/android/disconnect

Google leaderboard submitting score doesn't work

Can you explane me why command Games.Leaderboards.submitScore(mGoogleApiClient, leaderboard_id, score) doesn't work? When I upload signed apk on Alpha testing: signing in works, loading leaderboard also works, but the leaderboard doesn't show any scores.
This is my MainActivity including all Google Services...
imports...
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener {
FragmentManager mFragmentManager;
FragmentTransaction mFragmentTransaction;
FrameLayout fragmentView;
int actualFragment;
public boolean accountConnected;
com.google.android.gms.common.SignInButton signIn;
Button signOut;
private GoogleApiClient mGoogleApiClient;
private static int RC_SIGN_IN = 9001;
private boolean mResolvingConnectionFailure = false;
private boolean mAutoStartSignInFlow = true;
private boolean mSignInClicked = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
accountConnected = prefs.getBoolean("accountIsConnected", false);
// Create the Google Api Client with access to the Play Games services
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
fragmentView = (FrameLayout) findViewById(R.id.fragmentView);
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.fragmentView, new MenuFragment()).commit();
actualFragment = 0;
signIn = (com.google.android.gms.common.SignInButton) findViewById(R.id.sign_in_button);
signIn.setOnClickListener(this);
signOut = (Button) findViewById(R.id.sign_out_button);
signOut.setOnClickListener(this);
}
public void loadLeaderboard() {
if(accountConnected) {
Intent leaderboard = new Intent(Games.Leaderboards.getAllLeaderboardsIntent(mGoogleApiClient));
startActivityForResult(leaderboard, 2);
}
}
public void loadClassicHighscore() {
if (accountConnected) {
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient, getString(R.string.classic_leaderboard_id), LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
#Override
public void onResult(final Leaderboards.LoadPlayerScoreResult scoreResult) {
if (isScoreResultValid(scoreResult)) {
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
prefs.edit().putInt("classic_highscore", (int) scoreResult.getScore().getRawScore()).apply();
}
}
});
}
}
public void loadZenHighscore() {
if (mGoogleApiClient.isConnected()) {
Games.Leaderboards.loadCurrentPlayerLeaderboardScore(mGoogleApiClient, getString(R.string.zen_leaderboard_id), LeaderboardVariant.TIME_SPAN_ALL_TIME, LeaderboardVariant.COLLECTION_PUBLIC).setResultCallback(new ResultCallback<Leaderboards.LoadPlayerScoreResult>() {
#Override
public void onResult(final Leaderboards.LoadPlayerScoreResult scoreResult) {
if (isScoreResultValid(scoreResult)) {
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
prefs.edit().putInt("zen_highscore", (int) scoreResult.getScore().getRawScore()).apply();
}
}
});
}
}
private boolean isScoreResultValid(final Leaderboards.LoadPlayerScoreResult scoreResult) {
return scoreResult != null && GamesStatusCodes.STATUS_OK == scoreResult.getStatus().getStatusCode() && scoreResult.getScore() != null;
}
public void submitClassicHighscore(long score) {
if(mGoogleApiClient.isConnected()) {
Games.Leaderboards.submitScore(mGoogleApiClient, String.valueOf(R.string.classic_leaderboard_id), score);
Games.Leaderboards.submitScoreImmediate(mGoogleApiClient, String.valueOf(R.string.classic_leaderboard_id), score);
} else {
Toast.makeText(this, "unable to submit highscore", Toast.LENGTH_SHORT).show();
}
}
public void submitZenHighscore(long score) {
if(mGoogleApiClient.isConnected()) {
Games.Leaderboards.submitScore(mGoogleApiClient, String.valueOf(R.string.zen_leaderboard_id), score);
} else {
Toast.makeText(this, "unable to submit highscore", Toast.LENGTH_SHORT).show();
}
}
// Call when the sign-in button is clicked
private void signInClicked() {
mSignInClicked = true;
mGoogleApiClient.connect();
}
// Call when the sign-out button is clicked
private void signOutclicked() {
mSignInClicked = false;
Games.signOut(mGoogleApiClient);
}
#Override
protected void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
if (prefs.getBoolean("accountIsConnected", false) == true) {
mGoogleApiClient.connect();
accountConnected = true;
prefs.edit().putBoolean("accountIsConnected", accountConnected).apply();
} else {
accountConnected = false;
prefs.edit().putBoolean("accountIsConnected", accountConnected).apply();
}
}
#Override
protected void onStop() {
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
prefs.edit().putBoolean("accountIsConnected", accountConnected).apply();
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(Bundle bundle) {
// show sign-out button, hide the sign-in button
signIn.setVisibility(View.GONE);
signOut.setVisibility(View.VISIBLE);
accountConnected = true;
loadClassicHighscore();
loadZenHighscore();
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
submitClassicHighscore(prefs.getInt("classic_highscore", 0));
submitZenHighscore(prefs.getInt("zen_highscore", 0));
prefs.edit().putBoolean("accountIsConnected", accountConnected).apply();
// (your code here: update UI, enable functionality that depends on sign in, etc)
}
#Override
public void onConnectionSuspended(int i) {
// Attempt to reconnect
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (mResolvingConnectionFailure) {
// Already resolving
return;
}
// If the sign in button was clicked or if auto sign-in is enabled,
// launch the sign-in flow
if (mSignInClicked || mAutoStartSignInFlow) {
mAutoStartSignInFlow = false;
mSignInClicked = false;
mResolvingConnectionFailure = true;
// Attempt to resolve the connection failure using BaseGameUtils.
// The R.string.signin_other_error value should reference a generic
// error string in your strings.xml file, such as "There was
// an issue with sign in, please try again later."
if (!BaseGameUtils.resolveConnectionFailure(this, mGoogleApiClient, connectionResult, RC_SIGN_IN, "Something went wrong!")) {
mResolvingConnectionFailure = false;
}
}
// Put code here to display the sign-in button
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == RC_SIGN_IN) {
mSignInClicked = false;
mResolvingConnectionFailure = false;
if (resultCode == RESULT_OK) {
mGoogleApiClient.connect();
} else {
accountConnected = false;
SharedPreferences prefs = getSharedPreferences("com.thematus.twinz", MODE_PRIVATE);
prefs.edit().putBoolean("accountIsConnected", accountConnected).apply();
BaseGameUtils.showActivityResultError(this, requestCode, resultCode, R.string.signin_failure);
}
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.sign_in_button) {
mSignInClicked = true;
mGoogleApiClient.connect();
}
else if (v.getId() == R.id.sign_out_button) {
// sign out.
mSignInClicked = false;
Games.signOut(mGoogleApiClient);
// show sign-in button, hide the sign-out button
signIn.setVisibility(View.VISIBLE);
signOut.setVisibility(View.GONE);
}
}
}
I'm using two leaderboards so it might be quite different than using only one.
Thanks for any reply
There was problem in leaderboard id, i have it stored in strings.xml and I was calling them like String.valueOf(R.string.id) which returns wrong. So I only manually wrote that string in "" which went.

Why is GoogleApiClient starting a different activity?

I have the following code which is part of a LoginActivity which is not the MAIN or LAUNCHER activity. This activity is started from the Application Class.
The problem is, after I press the Login button, the Dialog from where I choose an account pops up, I choose one, press the OK button, and afterwards my onStop method is called and the MAIN activity is shown. No other method (including OnConnected) seems to be called afterwards.
Is this a limitation of the GoogleApiClient where I can only use it from the Main Activity ? I haven't been able to find anything regarding this and I have tried changing the Activity to a FragmentActivity with no luck...
#EActivity(R.layout.activity_login)
public class LoginActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
#App
MyApp app;
#ViewById(R.id.layout_login)
LinearLayout layoutLogin;
#ViewById(R.id.layout_loading)
RelativeLayout layoutLoading;
#ViewById(R.id.layout_error)
RelativeLayout layoutError;
private static final int RC_SIGN_IN = 0;
private GoogleApiClient mGoogleApiClient;
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (IntentSender.SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.build();
}
#Override
public void onConnected(Bundle bundle) {
layoutLoading.setVisibility(View.VISIBLE);
layoutLogin.setVisibility(View.GONE);
mSignInClicked = false;
}
#Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!mIntentInProgress) {
mConnectionResult = result;
if (mSignInClicked) {
resolveSignInError();
}
}
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Click(R.id.button_sign_in)
public void signInButtonClicked() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
}
It seems setting this in the AndroidManifest results in GoogleApiClient closing the activity in which it resides if it is not the main activity.
android:noHistory="true"

Logging out after successful Google+ sign in

This is a long question and might be confusing, please bear with me.
So i successfully created a Google+ sign in for my Android app following the instructions on the developers.google.com website and it successfully signs a user in.Here is the code of my main Activity.
//..imports
#SuppressWarnings("unused")
public class MainActivity extends Activity implements
ConnectionCallbacks, OnConnectionFailedListener, View.OnClickListener {
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final String TAG = "MainActivity";
private ProgressDialog mConnectionProgressDialog;
private static PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlusClient = new PlusClient.Builder(this, this, this)
.setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.setScopes(Scopes.PLUS_LOGIN) // recommended login scope for social features
// .setScopes("profile") // alternative basic login scope
.build();
// Progress bar to be displayed if the connection failure is not resolved.
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
}
#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);
findViewById(R.id.sign_in_button).setOnClickListener(this);
return true;
}
protected void onStart() {
super.onStart();
mPlusClient.connect();
}
protected void onStop() {
super.onStop();
mPlusClient.disconnect();
}
public PlusClient getMplusClient() {
return mPlusClient;
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
// Save the intent so that we can start an activity when the user clicks
// the sign-in button.
mConnectionResult = result;
}
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, TestActivity.class));
}
public void onDisconnected() {
Log.d(TAG, "disconnected");
}
public void startTestActivity() {
startActivity(new Intent(this, TestActivity.class));
}
#Override
public void onClick(View view) {
if (view.getId() == R.id.sign_in_button && !mPlusClient.isConnected()) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
} } } }
}//end of class
`
Now i added a new activity to my project called TestActivity where i have the code to sign a user out of the app.And this TestActivity is started in the MainActivity from the block
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, TestActivity.class));
}
This works fine and the TestActivity is started when a user is connected to the app, and when i run the app again, this is the activity is see(since the user is still signed in).
Now, the problem is the logout button in the TestActivity class does not do anything.Google's Sign Out method is
public void onClick(View view) {
if (view.getId() == R.id.sign_out_button) {
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
}
}
}
Since mPlusClient is in the MainActivity and is declared as private i added the getMPlusCLient() method you see in the MainActivity (I think this is where my problem starts) which returns mPlusClient, a PlusClient object.Now, i ended up with this as my TestActivity
public class TestActivity extends Activity implements View.OnClickListener{
private Button sign_out_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test, menu);
sign_out_button = (Button)findViewById(R.id.signOutButton);
sign_out_button.setOnClickListener(this);
return true;
}
public void signOut() {
MainActivity signOutObject = new MainActivity();
if (signOutObject.getMplusClient().isConnected()) {
signOutObject.getMplusClient().clearDefaultAccount();
signOutObject.getMplusClient().disconnect();
signOutObject.getMplusClient().connect();
}
}
#Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.signOutButton:
signOut();
break;
}
}
}
The problem like i stated earlier is the logout button in my TestActivity class does not do anything and no error message is shown in logcat.Where did i go wrong?

Google+ sign out from a different activity

I have started using the Google+ API for android, and I have created a sign-in application following this tutorial:
https://developers.google.com/+/mobile/android/sign-in
Now, the problem is that I want to create the sign out button from a different Activity, and what i tried to do didn't really worked..
My GPlusLogin code (Activity for the Google+ Login):
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import com.google.android.gms.common.*;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.plus.PlusClient;
public class GPlusLogin extends Activity implements ConnectionCallbacks, OnConnectionFailedListener{
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final String TAG = "GPlusLogin";
private ProgressDialog mConnectionProgressDialog;
private PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.gplus_layout);
mPlusClient = new PlusClient.Builder(this, this, this).setVisibleActivities("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity").build();
Bundle extras = getIntent().getExtras();
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
if(extras!=null){
if(extras.getString("signout")!=null){
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
finish();
startActivity(getIntent());
}
}
}else{
findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
// TODO Auto-generated method stub
if (view.getId() == R.id.sign_in_button && !mPlusClient.isConnected()) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult.startResolutionForResult(GPlusLogin.this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
}
}
}
}
});
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
mPlusClient.connect();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
mPlusClient.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
mConnectionResult = result;
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
#Override
public void onConnected() {
// TODO Auto-generated method stub
mConnectionProgressDialog.dismiss();
Intent main = new Intent(GPlusLogin.this, MainActivity.class);
main.putExtra("result", true);
startActivity(main);
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
Log.d(TAG, "disconnected");
}
}
My Disconnect code on MainActivity:
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if(extras==null){
Intent intent = new Intent(this, GPlusLogin.class);
startActivity(intent);
}
TextView text1 = (TextView) findViewById(R.id.text1);
text1.setText("You Are Connected :D");
Button SignOut = (Button) findViewById(R.id.sign_out_gplus);
SignOut.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, GPlusLogin.class);
intent.putExtra("signout", true);
startActivity(intent);
}
});
}
#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;
}
}
Just add this on your new activity, where you want your logout-button for google+ to be there :
#Override
protected void onStart() {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
mGoogleApiClient.connect();
super.onStart();
}
and next:
signout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
Toast.makeText(getApplicationContext(),"Logged Out",Toast.LENGTH_SHORT).show();
Intent i=new Intent(getApplicationContext(),MainActivity.class);
startActivity(i);
}
});
}
});
Hey i solved this problem by myself, working like charm
What is the problem : Google plus signIn in one activity but need to Logout from another activity
Solution:
My Google-plus Logout Activity is like this:
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener,
ResultCallback<People.LoadPeopleResult> {
GoogleApiClient mGoogleApiClient;
boolean mSignInClicked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
//copy this code on "Logout" Onclick
logout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
// updateUI(false);
System.err.println("LOG OUT ^^^^^^^^^^^^^^^^^^^^ SUCESS");
}
}
});
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
mSignInClicked = false;
// updateUI(true);
Plus.PeopleApi.loadVisible(mGoogleApiClient, null).setResultCallback(
this);
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
mGoogleApiClient.connect();
// updateUI(false);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onResult(LoadPeopleResult arg0) {
// TODO Auto-generated method stub
}
Description about solution:
For single package google plus API will generate one token & session.Just here simply make one more session in logout page also.You can easily logout from session now
I to have tried a lot about this problem,to logout from current session, just try this .it will definitely work. any doubts let me know
It would probably be easier to create a base class and inherit the connect/disconnect methods. Photohunt, our full sample, documents this design in detail.
Docs
Code
You can get instance of FirebaseAuth anywhere from the app as FirebaseAuth is a singleton class.
mAuth = FirebaseAuth.getInstance();
mAuth.signOut();
After struggling for over a week to find out the answer.
I did this,
After signing in save boolean isSignedIn in sharedpreferences as true.
private SharedPreferences.Editor editor;
private SharedPreferences prefs;
editor = getSharedPreferences(getString(R.string.userDetails), MODE_PRIVATE).edit();
editor.putBoolean(getString(R.string.isSignedIn), true);
editor.apply();`
Now from any activity when the user clicks logout, change the boolean to false.
In your Login Activity where googleApiClient is build. In its onStart method.
Check if isSignedIn is false.
#Override
public void onStart() {
super.onStart();
if (!prefs.getBoolean(getString(R.string.isSignedIn), false)) {
signOut();
}
}
Do the same in onConnected
#Override
public void onConnected(Bundle connectionHint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "onConnected: " + "yes it is connected");
if (!prefs.getBoolean(getString(R.string.isSignedIn), false)) {
signOut();
}
}
}
This will logout and revokeAccess.
public void signOut() {
if (mGoogleApiClient != null) {
Log.e(TAG, "signOut: " + mGoogleApiClient + mGoogleApiClient.isConnected());
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
if (mGoogleApiClient.isConnected()) {
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
Log.i(TAG, "onResult: " + mGoogleApiClient);
}
});
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.i(TAG, "onResult: Revoke Access status:" + status.getStatus());
}
});
}
}
}
Once you click logout from another activity,try send an intent with extra to indicate that logout button is clicked. Then on Login Activity
if (Intent.Extras != null && Intent.Extras.ContainsKey("LogoutAction")) {
_logoutRequest = Intent.Extras.GetBoolean("LogoutAction");
}
if (_logoutRequest) {
await PlusClass.AccountApi.RevokeAccessAndDisconnect(_apiClient);
_apiClient.Disconnect();
_apiClient.Connect ();
_logoutRequest = false;
}
Other Activity
var intent = new Intent(this.Activity,typeof(LoginActivity));
intent.PutExtra("LogoutAction",true);
Jonathan is correct that a base class or a fragment would make your life easier. That said, the code here could work - the problem is that you're checking whether the PlusClient is connected in onCreate() - but you don't connect it until onStart(). You'd probably need to check the intent in the onConnected() method, and perform the sign out there.
sommesh's answer is perfect, but for less code you can use "Public Static Method" like this:
public static GoogleApiClient mGoogleApiClient;
...
...
public static void signOutFromGoogle() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
//...
}
});
}
And on your other Activity call it:
Your_Google_Activity.mGoogleApiClient.connect();
btnSignOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Your_Google_Activity.signOutFromGoogle();
}
});
Here's my solution. I have made a Utils singleton class. In my LoginActivity, I have a GoogleSignInClient object. So just before starting the DashboardActivity after login, I save the instance of googleSignInClient object by calling Utils.getInstance().setGoogleSignInClient(googleSignInClient). Now anywhere else, if I want to logout I have this method in Utils ready:
public void signOut() {
googleSignInClient.signOut();
FirebaseAuth.getInstance().signOut();
}
So now, I can do this from any other activity:
else if (id == R.id.action_logout) {
Utils.getInstance().signOut();
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}
Yes, you need to log out from both of them, otherwise, you might not see the account chooser the next time you tap the login button.

Categories

Resources