Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "Already managing a GoogleApiClient with id 0" exception when using TabLayout Viewpager

I want to integrate Google Signup using TabLayout ViewPager Fragments. ViewPager contains two fragments LoginFragment and RegistrationFragment and both contains "Google Signup" button.

Problem is that I'm getting following error when launch activity.

java.lang.IllegalStateException: Already managing a GoogleApiClient with id 0

Complete error log-

java.lang.IllegalStateException: Already managing a GoogleApiClient with id 0
at com.google.android.gms.common.internal.zzac.zza(Unknown Source)
at com.google.android.gms.internal.zzzt.zza(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.zzf(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source)
at com.naturesouq_shopping.fragment.RegistrationFragment.buildGoogleApiClient(RegistrationFragment.java:174)
at com.naturesouq_shopping.fragment.RegistrationFragment.getIds(RegistrationFragment.java:140)
at com.naturesouq_shopping.fragment.RegistrationFragment.onCreateView(RegistrationFragment.java:85)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2184)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1298)
at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1969)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
at android.view.View.measure(View.java:20236)

I'm trying following code

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

 // Configure sign-in to request the user's ID, email address, and basic
 // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        buildGoogleApiClient();

     // .....
 }

private synchronized void buildGoogleApiClient() {
    /** build_client */
   try {
       mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
               .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */)
               .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
               .build();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

and

@Override
public void onStart() {
    super.onStart();
    if (mGoogleApiClient != null) {
        mGoogleApiClient.connect();
    } 

}

@Override
public void onStop() {
    Log.d("GARG", "***** on Stop ***** ");
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        Log.d("GARG", "***** on Stop mGoogleApiClient disconnect ***** ");

        mGoogleApiClient.stopAutoManage(getActivity());
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

Is there another way to connect Google API client? Any idea on where i am doing wrong and the correct way ?

like image 229
Garg's Avatar asked Feb 09 '17 13:02

Garg's


2 Answers

I think you are attempting to build and connect through the googleApiClient which has already been built and connected. This may solve your problem:

if(mGoogleApiClient == null || !mGoogleApiClient.isConnected()){
 try {
   mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
           .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */)
           .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
           .build();
 } catch (Exception e) {
   e.printStackTrace();
 }
}
like image 89
Niraj Niroula Avatar answered Oct 31 '22 19:10

Niraj Niroula


The official doc for enableAutoManage says this:

At any given time, only one auto-managed client is allowed per id. To reuse an id you must first call stopAutoManage(FragmentActivity) on the previous client.

Your code is using the version of enableAutoManage without a clientId parameter, so it's defaulting to 0. Below I explain why you will have multiple auto-managed clients for clientId 0, which is what the above documentation is warning against.

After one of your Fragments is attached to a FragmentActivity, it tells that activity to start managing a new instance of GoogleApiClient. But what if the FragmentActivity is already managing another instance of GoogleApiClient? That's when you get the error.

In your case, your FragmentActivity that contains the ViewPager is asked to managed two different GoogleApiClients, one from RegistrationFragment and one from LoginFragment. According to the stack trace, the FragmentActivity started managing LoginFragment's GoogleApiClient first, then crashed when you asked it to manage RegistrationFragment's GoogleApiClient.

You could try a few things:

  • Pass two different clientIds to enableAutoManage, one for LoginFragment and another for ReservationFragment.
  • Figure out where you need to call stopAutoManage. This might be tricky with Fragments in a ViewPager.
  • If I were you, I'd seriously consider creating the GoogleApiClient in the FragmentActivity that contains the ViewPager instead of in RegistrationFragment and LoginFragment. Then you could either do the work that requires GoogleApiClient in the Activity, or continue to do it in both Fragments after getting the GoogleApiClient from the Activity like so:

private GoogleApiClient googleApiClient;

  @Override
  void onAttach(Activity activity) {
      super.onAttach(activity);
      googleApiClient = activity.getGoogleApiClient();
  }

  @Override
  void onDetach() {
      super.onDetach();
      googleApiClient = null;
  }
like image 41
vlazzle Avatar answered Oct 31 '22 20:10

vlazzle