Everything works right the first time, if you launch a second time you see this error:
FATAL EXCEPTION: main Process: ro.vrt.videoplayerstreaming, PID: 23662 java.lang.IllegalStateException: Already managing a GoogleApiClient with id 0 at com.google.android.gms.common.internal.zzx.zza(Unknown Source) at com.google.android.gms.common.api.internal.zzw.zza(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.zza(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.zze(Unknown Source) at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source) at ro.vrt.videoplayerstreaming.Login.onCreateView(Login.java:75) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5849) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:763) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
Here’s my code:
public class Login extends Fragment implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { private static final String TAG = "SignInActivity"; private static final int RC_SIGN_IN = 9001; private GoogleApiClient mGoogleApiClient; private TextView mStatusTextView; private ProgressDialog mProgressDialog; private static String url; private static View view; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (view != null) { ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) parent.removeView(view); } try { view = inflater.inflate(R.layout.activity_login, container, false); // Views mStatusTextView = (TextView) view.findViewById(R.id.status); // Button listeners view.findViewById(R.id.sign_in_button).setOnClickListener(this); view.findViewById(R.id.sign_out_button).setOnClickListener(this); view.findViewById(R.id.disconnect_button).setOnClickListener(this); // [START configure_signin] // Configure sign-in to request the user's ID, email address, and basic // profile. ID and basic profile are included in DEFAULT_SIGN_IN. GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); // [END configure_signin] // [START build_client] // Build a GoogleApiClient with access to the Google Sign-In API and the // options specified by gso. mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity()/* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); // [END build_client] // [START customize_button] // Customize sign-in button. The sign-in button can be displayed in // multiple sizes and color schemes. It can also be contextually // rendered based on the requested scopes. For example. a red button may // be displayed when Google+ scopes are requested, but a white button // may be displayed when only basic profile is requested. Try adding the // Scopes.PLUS_LOGIN scope to the GoogleSignInOptions to see the // difference. SignInButton signInButton = (SignInButton) view.findViewById(R.id.sign_in_button); signInButton.setSize(SignInButton.SIZE_STANDARD); signInButton.setScopes(gso.getScopeArray()); // [END customize_button] } catch (InflateException e) { /* map is already there, just return view as it is */ } super.onCreate(savedInstanceState); return view; } @Override public void onStart() { super.onStart(); 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) { //adaugat de mine sa porneacsa singur cererea de logare signIn(); //fin hideProgressDialog(); handleSignInResult(googleSignInResult); } }); } } // [START onActivityResult] @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); handleSignInResult(result); } } // [END onActivityResult] // [START handleSignInResult] private void handleSignInResult(GoogleSignInResult result) { Log.d(TAG, "handleSignInResult:" + result.isSuccess()); if (result.isSuccess()) { // Signed in successfully, show authenticated UI. GoogleSignInAccount acct = result.getSignInAccount(); mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName() + " Your token " + acct.getId())); url = "http://grupovrt.ddns.net:81/index.php?token="+acct.getId(); updateUI(true); } else { // Signed out, show unauthenticated UI. updateUI(false); } } // [END handleSignInResult] // [START signIn] private void signIn() { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } // [END signIn] // [START signOut] private void signOut() { Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { // [START_EXCLUDE] updateUI(false); // [END_EXCLUDE] } }); } // [END signOut] // [START revokeAccess] private void revokeAccess() { Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(Status status) { // [START_EXCLUDE] updateUI(false); // [END_EXCLUDE] } }); } // [END revokeAccess] @Override public void onConnectionFailed(ConnectionResult connectionResult) { // An unresolvable error has occurred and Google APIs (including Sign-In) will not // be available. Log.d(TAG, "onConnectionFailed:" + connectionResult); } private void showProgressDialog() { if (mProgressDialog == null) { mProgressDialog = new ProgressDialog(getActivity()); mProgressDialog.setMessage(getString(R.string.loading)); mProgressDialog.setIndeterminate(true); } mProgressDialog.show(); } private void hideProgressDialog() { if (mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.hide(); } } private void updateUI(boolean signedIn) { if (signedIn) { getView().findViewById(R.id.sign_in_button).setVisibility(View.GONE); getView().findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE); } else { mStatusTextView.setText(R.string.signed_out); getView().findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE); getView().findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.sign_in_button: signIn(); break; case R.id.sign_out_button: signOut(); break; case R.id.disconnect_button: revokeAccess(); break; } } }
As I understand it, the problem is in these lines:
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .enableAutoManage(getActivity()/* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build();
I tried explicitly passing an id of 0
:
.enableAutoManage(getActivity() /* FragmentActivity */, 0, this /* OnConnectionFailedListener */)
but that still didn’t work.
What am I missing?
Advertisement
Answer
You should call stopAutoManage()
in the onPause()
method of your Fragment
:
@Override public void onPause() { super.onPause(); mGoogleClient.stopAutoManage(getActivity()); mGoogleClient.disconnect(); }