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.
Related
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
i have one login activity in which i am login using google. after successfully login i am moving to main screen. which has navigation drawer. now from the list of fragments, i want to sign out from google using one of fragment. how can i achieve this. below is my code:
LoginActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Session Manager
session = new SessionManager(getApplicationContext());
initUi();
setupListeners();
}
protected void onStart() {
super.onStart();
}
protected void onStop() {
super.onStop();
if (MyApplication.mGoogleApiClient.isConnected()) {
MyApplication.mGoogleApiClient.disconnect();
}
}
private void initUi(){
llGoogle = (LinearLayout)findViewById(R.id.activity_login_llsignin_google);
}
private void setupListeners(){
llGoogle.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (session.isConnected()) {
getProfileInformation();
} else {
}
}
});
}
private void resolveSignInError() {
if (MyApplication.mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
MyApplication.mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
MyApplication.mGoogleApiClient.connect();
}
}
}
private void googlePlusLogin() {
MyApplication.googlePlusLogin();
resolveSignInError();
}
MyApplication.java
public class MyApplication extends Application implements
ConnectionCallbacks, OnConnectionFailedListener,
ResultCallback<People.LoadPeopleResult>{
public static Typeface app_medium;
public static Typeface app_regular;
public static Typeface app_bold;
public static final String TAG = MyApplication.class.getSimpleName();
private static SharedPreferences Pref;
private static MyApplication mInstance;
private static final int RC_SIGN_IN = 0;
// Google client to communicate with Google
public static GoogleApiClient mGoogleApiClient;
public boolean mIntentInProgress;
public static boolean signedInUser;
public static ConnectionResult mConnectionResult;
#SuppressWarnings("unused")
public void onCreate() {
super.onCreate();
mInstance = this;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
Pref = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
checkFBKey();
app_regular = Typeface.createFromAsset(getAssets(),
"fonts/dax_regular.ttf");
app_medium = Typeface.createFromAsset(getAssets(),
"fonts/dax_medium.ttf");
app_bold = Typeface.createFromAsset(getAssets(),
"fonts/dax_bold.ttf");
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
/**
* set user login
* */
// public static void setUserFBLogin() {
// // TODO Auto-generated method stub
// Editor edit_login_detail = Pref.edit();
// edit_login_detail.putBoolean(GeneralClass.temp_iUserFaceBookBLOGIN,
// true);
// edit_login_detail.commit();
// }
public void checkFBKey() {
PackageInfo info;
try {
info = getPackageManager().getPackageInfo(getPackageName(),
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
// String something = new
// String(Base64.encodeBytes(md.digest()));
Log.e("hash key", something);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}
}
public static void googlePlusLogin() {
if (!mGoogleApiClient.isConnecting()) {
signedInUser = true;
}
}
public static void googlePlusLogout() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
// updateProfile(false);
}
}
public static void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e("LOGIN", "User access revoked!");
mGoogleApiClient.connect();
}
});
}
}
#Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
}
#Override
public void onResult(LoadPeopleResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
if (!arg0.hasResolution()) {
return;
}
if (!mIntentInProgress) {
// store mConnectionResult
MyApplication.mConnectionResult = arg0;
if (signedInUser) {
}
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
Log.e("APPLICATION", "CONNECTED");
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
mGoogleApiClient.connect();
}
}
Now, i want to use googlePlusLogout() method in my fragment. how can i do that.?
You should implement all your global credential and methods in Application class so you call it from any Activity or Fragment class.
Declare Set your LoginActivity as CurrentActivity in Application class and using instanceOf call loginSuccessful method of LoginActivity from Application at onConnected() method. and you can call logOut method from Fragment of an Application class.
Check Follow Example.
/**
* #author AA-Sk
*
*/
public class MyApplication extends Application {
private Activity mCurrentActivity;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onConnected(Bundle mBundle) {
Activity mActivity = getmCurrentActivity();
if (mActivity != null) {
if (mActivity instanceof LoginActivity) {
LoginActivity mLoginActivity = (LoginActivity) mActivity;
mLoginActivity.loginSuccessfull(mBundle);
}
}
}
private void googleLogout() {
}
public void setmCurrentActivity(Activity mCurrentActivity) {
this.mCurrentActivity = mCurrentActivity;
}
public Activity getmCurrentActivity() {
return mCurrentActivity;
}
/**
* #author AA-Sk
*
*/
public class LoginActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((MyApplication) getApplication()).setmCurrentActivity(LoginActivity.this);
}
private void loginSuccessfull(Bundle mBundle) {
// Store Data from bundle and call another activity as user is successfully logged in.
}
}
/**
* #author AA-Sk
*
*/
public class SampleActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
/**
* #author AA-Sk
*
*/
public class logout extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
public logout() {
((MyApplication) getActivity().getApplication()).googleLogout();
}
}
}
Im running into a problem when trying to submit a score to my Play Services Leader board. From my MainActivity the user is logged in successfully then from my GameScreen activity I try to submit a score but it fails:(...My Question is does the connection persist or do I have to reconnect the user before I submit???
MAIN ACTIVITY.
public class MainActivity extends BaseGameActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
Button siButton;
private GoogleApiClient mGoogleApiClient;
#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)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
siButton = (Button) findViewById(R.id.sign_out_button);
siButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view.getId() == R.id.sign_in_button) {
beginUserInitiatedSignIn();
} else if (view.getId() == R.id.sign_out_button) {
signOut();
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onSignInSucceeded() {
findViewById(R.id.sign_in_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
}
#Override
public void onSignInFailed() {
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
#Override
public void onClick(View v) {
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
GAMESCREEN
public class GameScreen extends BaseGameActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private int c;
private GoogleApiClient mGoogleApiClient;
TextView counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_screen);
setRequestedClients(BaseGameActivity.CLIENT_GAMES | BaseGameActivity.CLIENT_APPSTATE);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
private void progressSetup() {
Thread timerThread = new
Thread() {
#Override
public void run() {
try {
while (mbActive && (waited < TIMER_RUNTIME)) {
sleep(THREAD_SLEEP);
if (mbActive) {
waited += 100;
updateProgress(waited);
if (waited > 9999) {
mbActive = false;
gameOver();
}
}
}
} catch (InterruptedException e) {
Log.d("fail", "failure" + e);
}
}
};
startTread = false;
timerThread.start();
}
private void updateProgress(final int timePassed) {
if (null != mProgressBar) {
progress = mProgressBar.getMax() * timePassed / TIMER_RUNTIME;
mProgressBar.setProgress(progress);
}
}
//game over
private void gameOver() {
runOnUiThread(new Runnable() {
#Override
public void run() {
upDateScore();
}
});
}
private void upDateScore(){
if (mGoogleApiClient.isConnected()) {
Games.Leaderboards.submitScore(mGoogleApiClient, getString(R.string.app_id), c);
Log.d("connectted.....................................................");
} else {
Log.d("not connectted.....................................................");
}
}
#Override
public void onBackPressed() {
Intent home = new Intent(GameScreen.this, MainActivity.class);
home.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(home);
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onSignInFailed() {
}
#Override
public void onSignInSucceeded() {
}
}
Just replace getString(R.string.app_id) with your LEADERBOARD id in method Games.Leaderboards.submitScore(mGoogleApiClient, getString(R.string.app_id).
Leaderboard id looks like this: "CgkI0tXt-q0HEA****"
Ivan Syabro is right. You must use the LEADERBOARD_ID, see Leaderboards in Android - Updating the player's score.
In the developer console's game services section, you can easily export your leaderboard and achievements ids as xml files using the provided button.
In general, using the game services with more than one activity might cause additional waiting periods as each of them signs in individually at its start. Therefore, as far as I know, the implementation with fragments should be preferred, see this famous example playgameservices/android-basic-samples.
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.
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?