I am following this tutorial it is working fine but in my app i have multiple activity like SplashActivity -->MainActivity-->MyNewMainActivity
MyNewMainActivtiy.java contains 3 fragment like SearchFragment--> NearbyFragment--> ProfileFragment
I have completing login successfully and get the profile information and set the name and picture in profileFragment i have set a logout button from where i want to logout from google plus and back to LoginActivity and when i click on googleplus login button again it shows error
07-02 11:24:04.815: E/AndroidRuntime(24382): FATAL EXCEPTION: main
07-02 11:24:04.815: E/AndroidRuntime(24382): java.lang.NullPointerException
07-02 11:24:04.815: E/AndroidRuntime(24382): at com.rstm.doctorrx.LoginActivity.resolveSignInError(LoginActivity.java:279)
07-02 11:24:04.815: E/AndroidRuntime(24382): at com.rstm.doctorrx.LoginActivity.signInWithGplus(LoginActivity.java:345)
07-02 11:24:04.815: E/AndroidRuntime(24382): at com.rstm.doctorrx.LoginActivity.onClick(LoginActivity.java:114)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.view.View.performClick(View.java:4222)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.view.View$PerformClick.run(View.java:17343)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.os.Handler.handleCallback(Handler.java:615)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.os.Handler.dispatchMessage(Handler.java:92)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.os.Looper.loop(Looper.java:137)
07-02 11:24:04.815: E/AndroidRuntime(24382): at android.app.ActivityThread.main(ActivityThread.java:4895)
07-02 11:24:04.815: E/AndroidRuntime(24382): at java.lang.reflect.Method.invokeNative(Native Method)
07-02 11:24:04.815: E/AndroidRuntime(24382): at java.lang.reflect.Method.invoke(Method.java:511)
07-02 11:24:04.815: E/AndroidRuntime(24382): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
07-02 11:24:04.815: E/AndroidRuntime(24382): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
07-02 11:24:04.815: E/AndroidRuntime(24382): at dalvik.system.NativeStart.main(Native Method)
LoginActivity.java
package com.rstm.doctorrx;
import java.util.ArrayList;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;
import com.doctorrx.integration.FacebookService;
import com.doctorrx.integration.FacebookService.FacebookFriendListRequester;
import com.doctorrx.integration.UserContext;
import com.doctorrx.integration.Utils;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
public class LoginActivity extends Activity implements OnClickListener , FacebookFriendListRequester,
ConnectionCallbacks, OnConnectionFailedListener{
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
public static int socialLogin;
private boolean mIntentInProgress;
private ConnectionResult mConnectionResult;
ImageButton cross_btn;
ProgressDialog dialog;
Button login_btn, signup_btn,google_btn,facbook_login_btn;
private boolean mSignInClicked;
private static final int RC_SIGN_IN = 0;
private SharedPreferences mPrefs;
// Logcat tag
private static final String TAG = "MainActivity";
// Google client to interact with Google API
private static GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_login);
cross_btn=(ImageButton)findViewById(R.id.cross_btn);
login_btn=(Button)findViewById(R.id.login_btn);
signup_btn=(Button)findViewById(R.id.register_btn);
google_btn=(Button)findViewById(R.id.google_login_btn);
facbook_login_btn=(Button)findViewById(R.id.facbook_login_btn);
initialiseGoogleclient();
facbook_login_btn.setOnClickListener(this);
google_btn.setOnClickListener(this);
login_btn.setOnClickListener(this);
signup_btn.setOnClickListener(this);
cross_btn.setOnClickListener(this);
// try {
// PackageInfo info = getPackageManager().getPackageInfo(
// "com.rstm.doctorrx", PackageManager.GET_SIGNATURES);
// for (Signature signature : info.signatures) {
// MessageDigest md = MessageDigest.getInstance("SHA");
// md.update(signature.toByteArray());
// Log.e("MY KEY HASH:",
// Base64.encodeToString(md.digest(), Base64.DEFAULT));
// }
// } catch (NameNotFoundException e) {
//
// } catch (NoSuchAlgorithmException e) {}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.facbook_login_btn:
socialLogin=404;
dialog = new ProgressDialog(this);
loadMyFriendList();
break;
case R.id.cross_btn:
startActivity(new Intent(v.getContext(),MainActivity.class));
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
finish();
break;
case R.id.login_btn:
startActivity(new Intent(v.getContext(),LoginDetailActivity.class));
overridePendingTransition( R.anim.slide_in_up, R.anim.slide_out_up );
break;
case R.id.register_btn:
startActivity(new Intent(v.getContext(),SignupActivity.class));
overridePendingTransition( R.anim.slide_in_up, R.anim.slide_out_up );
break;
case R.id.google_login_btn:
socialLogin=401;
initialiseGoogleclient();
signInWithGplus();
break;
}
}
private void initialiseGoogleclient() {
// TODO Auto-generated method stub
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
private void loadMyFriendList() {
// TODO Auto-generated method stub
if (Utils.haveNetworkConnection(this)) {
dialog.setMessage("Verifying credentials...");
dialog.show();
FacebookService.instance().setContext(getApplicationContext());
if (!Utils.isAuthenticated()) {
FacebookService.instance().fetchFacebookProfile(this);
} else {
UserContext.authorized = true;
startActivity(new Intent(this,MyNewMainActivity.class));
overridePendingTransition( R.anim.slide_in_left, R.anim.slide_out_left);
dialog.dismiss();
finish();
}
}
}
@Override
public void onListFetched(ArrayList<JSONObject> onLinefriends,
ArrayList<JSONObject> idleLinefriends,
ArrayList<JSONObject> offLinefriends) {
// TODO Auto-generated method stub
//dialog.dismiss();
}
@Override
public void onFbError() {
// TODO Auto-generated method stub
dialog.dismiss();
}
public void onFacebookProfileRetreived(boolean isSuccess) {
// override this method
if (isSuccess) {
startActivity(new Intent(this,MyNewMainActivity.class));
overridePendingTransition( R.anim.slide_in_left, R.anim.slide_out_left);
dialog.dismiss();
finish();
} else {
Toast.makeText(this, "Some Error occurred!", Toast.LENGTH_LONG).show();
dialog.dismiss();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
if(socialLogin==404){
if (!UserContext.authorized) {
FacebookService.instance().authorizeCallback(requestCode,
resultCode, data);
UserContext.authorized = true;
//dialog.dismiss();
}
}
if(socialLogin==401)
{
if (requestCode == RC_SIGN_IN)
{
if (resultCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
}
// public void onStart() {
// super.onStart();
// if (!Utils.haveNetworkConnection(this)) {
// showNoConnectionDialog();
// }
// }
private void showNoConnectionDialog() {
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
alt_bld.setMessage("Error in Network Connection!").setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
AlertDialog alert = alt_bld.create();
alert.setTitle("Error!");
alert.setIcon(R.drawable.ic_launcher);
alert.show();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
@Override
public void onConnected(Bundle paramBundle) {
// TODO Auto-generated method stub
mSignInClicked = false;
// Get user's information
getProfileInformation();
if(socialLogin==401){
startActivity(new Intent(this,MyNewMainActivity.class));
overridePendingTransition( R.anim.slide_in_left, R.anim.slide_out_left);
finish();}
}
@Override
public void onConnectionSuspended(int paramInt) {
// TODO Auto-generated method stub
mGoogleApiClient.connect();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
// personPhotoUrl = personPhotoUrl.substring(0,
// personPhotoUrl.length() - 2);
if(mPrefs == null){
mPrefs = this.getSharedPreferences("MyGamePreferences", android.content.Context.MODE_PRIVATE);
}
SharedPreferences.Editor editor = mPrefs.edit();
editor.putInt("login",401);
editor.putString("Guser_name", personName);
editor.putString("Guserpic_url", personPhotoUrl);
editor.commit();
UserContext.MyPicUrl=personPhotoUrl;
UserContext.MyDisplayName=personName;
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
public static void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
//mGoogleApiClient.connect();
}
}
/**
* Revoking access from google
* */
public 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(TAG, "User access revoked!");
mGoogleApiClient.connect();
}
});
}
}
}
profileFragment
public class ProfileFragment extends Fragment {
SharedPreferences mPrefs;
Button logout_btn;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.profile_layout, container, false);
TextView name =(TextView)rootView.findViewById(R.id.my_name);
ImageView myimage=(ImageView)rootView.findViewById(R.id.my_pic);
logout_btn=(Button)rootView.findViewById(R.id.logout_btn);
logout_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Editor editor = mPrefs.edit();
// for Normal Login
if(mPrefs.getInt("login", -404)==201)
{
editor.putString("normal_login_username", "");
editor.putInt("normallogin", -201);
}
// for Gmail
if(mPrefs.getInt("login", -404)==401)
{
LoginActivity.signOutFromGplus();
LoginActivity.socialLogin=-10;
editor.putInt("login", -401);
}
// for Facebook
if(mPrefs.getInt("login", -404)==404)
{
new MyAsyncTask().execute();
editor.putInt("login", -404);
}
editor.commit();
Intent intent = new Intent(getActivity(),LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
getActivity().finish();
}
});
if(mPrefs == null){
mPrefs = getActivity().getSharedPreferences("MyGamePreferences", android.content.Context.MODE_PRIVATE);
}
if(mPrefs.getInt("login", -401)==401){
name.setText(mPrefs.getString("Guser_name", "Dummy User"));
Utils.loadImageFromUrl(myimage, mPrefs.getString("Guserpic_url", "nothing found"));
}
if(mPrefs.getInt("login", -404)==404)
{
name.setText(mPrefs.getString("display_name", "Dummy User"));
Utils.loadImageFromUrl(myimage, mPrefs.getString("profile_url", "nothing found"));
}
if(mPrefs.getInt("login", -404)==201)
{
name.setText(mPrefs.getString("normal_login_username", "Dummy User"));
}
return rootView;
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.activity_main_actions, menu);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public class MyAsyncTask extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
FacebookService.instance().signout();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
my problem is how to logout form another fragmnet/activity from googleplus. Any idea will be appreciated
There are 2 ways to handle this problem,
Initialize GooglePlusClient making global throughout the application using singleton class/initializing it in application class.
Or you have to initialize the gplusclient in all activity(For that, write an abstract/base activity class with all gplus functionalities like sigin,signout and extend this base class in all activity where you want to handle gplus functions.
One more suggestion: Handle GplusClient object (like logout/login )in activity instead of fragment.Logic to communitcate between fragments/activity is as follow
For example(BaseActivity example)
public class GplusBaseActivity extends Activity implements PlusClientFragment.OnSignedInListener {
public static final int REQUEST_CODE_PLUS_CLIENT_FRAGMENT = 1550;
public static final int REQUEST_CODE_PLUS_CLIENT_PICK = 1551;
public static final int REQUEST_CODE_PLUS_CLIENT_API = 1552;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private PlusClientFragment mGPlusSignInFragment;
protected PlusClient mPlusClient;
protected Context mContext;
protected LoginHelper.GplusLoginCallback mOnGplusLoginCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
mGPlusSignInFragment =
PlusClientFragment.getPlusClientFragment(this, MomentUtil.ACTIONS);
}
@Override
public void setupActionBar(ActionBar actionBar) {
}
public Context getContext() {
return this;
}
public Activity getActivity() {
return this;
}
public void gplusLogin(LoginHelper.GplusLoginCallback gplusLoginCallback) {
mOnGplusLoginCallback = gplusLoginCallback;
mGPlusSignInFragment.signIn(REQUEST_CODE_PLUS_CLIENT_FRAGMENT);
}
@Override
public void onSignedIn(PlusClient plusClient) {
mPlusClient = plusClient;
Person currentPerson = plusClient.getCurrentPerson();
// After signin code
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_PLUS_CLIENT_FRAGMENT) {
L.d("onActivityResult: from G+,requestCode: " + requestCode + ", resultCode:" + resultCode);
mGPlusSignInFragment.handleOnActivityResult(requestCode, resultCode, data);
}
}
private boolean servicesConnected() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
//L.d("Google Play services is available.");
return true;
} else {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode, this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getSupportFragmentManager(),
"Locations Updates");
}
return false;
}
}
public void showSelectAccountsUI() {
try {
Intent intent = AccountPicker
.newChooseAccountIntent(null, null,
new String[]{"com.google"}, true, null, null,
null, null);
startActivityForResult(intent,
REQUEST_CODE_PLUS_CLIENT_PICK);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
L.wrong(mContext);
servicesConnected();
}
}
private static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
public void gplusLogout() {
if (mPlusClient != null) {
L.d("Loggin out G+");
plusSignOut(mPlusClient);
}
}
private void plusSignOut(PlusClient plusClient) {
if (plusClient.isConnected()) {
plusClient.clearDefaultAccount();
plusClient.disconnect();
}
}
public void logout(View view) {
gplusLogout();
}
}
Example for your Main activity with fragments:
Suppose you have LogoutFragment where you want to logout from g+
public class LogoutFragment extends Fragment {
LogoutFragmentListener mLogoutFragmentListener;
public interface LogoutFragmentListener{
public void onLogoutBtnClick();
}
Button mLogoutButton; // this is your sign-out btn
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
mLogoutFragmentListener=(LogoutFragmentListener)activity;
}catch (Exception e){
throw new IllegalStateException("Parent activity should implement LogoutFragmentListener");
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mLogoutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLogoutFragmentListener.onLogoutBtnClick();
}
});
}
...
...
}
and your main activity as
public class MainActivity extends GplusBaseActivity implements LogoutFragment.LogoutFragmentListener {
...
...
@Override
public void onLogoutBtnClick(){
gplusLogout(); // method from super class
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With