El cierre de sesión de otra actividad en Google más la integración no es un trabajo

Estoy siguiendo este tutorial está funcionando bien, pero en mi aplicación tengo varias actividades como SplashActivity -> MainActivity -> MyNewMainActivity

MyNewMainActivtiy.java contiene 3 fragmentos como SearchFragment -> NearbyFragment -> ProfileFragment

Tengo que terminar la conexión con éxito y conseguir la información del perfil y fijar el nombre y la imagen en profileFragment que he fijado un botón de la salida de donde deseo salir de google más y de nuevo a LoginActivity y cuando hago clic en googleplus

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(); } }); } } } 

Perfilfragmento

 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; } } } 

Mi problema es cómo cerrar la sesión forma otra fragmnet / actividad de googleplus. Cualquier idea será apreciada

Hay 2 maneras de manejar este problema,

  • Inicializar GooglePlusClient haciendo global en toda la aplicación utilizando singleton clase / inicializarlo en la clase de aplicación.

  • O bien, hay que inicializar el gplusclient en toda la actividad (para ello, escriba una clase de actividad abstracta / base con todas las funcionalidades gplus como sigin, signout y extender esta clase base en toda la actividad en la que desee manejar las funciones gplus.

Una sugerencia más: manejar el objeto GplusClient (como logout / login) en la actividad en lugar de fragment.Logic para comunicarse entre los fragmentos / actividad es la siguiente

  • Definir una interfaz en su fragmento
  • Implementar esa interfaz en la actividad
  • Comunicarse a través de esta interfaz (por ejemplo: si tiene un botón en fragmento, en el botón de clic, llame a la función de interfaz, que se implementa por actividad, y manejarlo en la actividad). El sitio de Google le ayudará (con ejemplos)

Por ejemplo (ejemplo de BaseActivity)

 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) { Ld("onActivityResult: from G+,requestCode: " + requestCode + ", resultCode:" + resultCode); mGPlusSignInFragment.handleOnActivityResult(requestCode, resultCode, data); } } private boolean servicesConnected() { int resultCode = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (ConnectionResult.SUCCESS == resultCode) { //Ld("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) { Ld("Loggin out G+"); plusSignOut(mPlusClient); } } private void plusSignOut(PlusClient plusClient) { if (plusClient.isConnected()) { plusClient.clearDefaultAccount(); plusClient.disconnect(); } } public void logout(View view) { gplusLogout(); } } 

Ejemplo para su actividad principal con fragmentos:

Supongamos que tiene LogoutFragment en el que desea salir de 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(); } }); } ... ... } 

Y su actividad principal como

 public class MainActivity extends GplusBaseActivity implements LogoutFragment.LogoutFragmentListener { ... ... @Override public void onLogoutBtnClick(){ gplusLogout(); // method from super class } } 

He resuelto mi problema mediante la implementación de ConnectionCallbacks y OnConnectionFailedListener interfaz en mi MyNewMainActivity.java que alojar todos mis fragmentos (Buscar, Cerca y Perfil) y llamada de salida función de ProfileFragment como este

 ((MyNewMainActivity)getActivity()).signOutFromGplus(); 
  • Obtención de un token de cuenta de Google de GoogleApiClient sin el permiso de GET_ACCOUNTS
  • ¿Cómo comprobar si un usuario ha iniciado sesión en Google+?
  • Com.google.android.gms.plus.PlusOneButton falló al instanciar
  • Cómo obtener direcciones de correo electrónico de círculos de Google Plus (Amigos agregados en círculos de Google y más)
  • Android Google Plus getCurrentPerson devuelve null
  • Los usuarios que se desconectan de Google+ espontáneamente
  • Google Plus GoogleApiClient connect () sin diálogo de selección de cuenta
  • Token de acceso recuperado: null. Com.google.android.gms.auth.GoogleAuthException: Desconocido
  • Android: inicio de sesión de Google con pantalla de inicio de sesión en lugar de inicio de sesión automático
  • Google Play Games - Actividad que llama automáticamente a beginUserInitiatedSignIn ()
  • Cómo compartir una imagen con la aplicación de Google+ mediante Intent.ACTION_SEND y Intent.EXTRA_STREAM
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.