GoogleApiClient.Builder.enableAutoManage in fragment throws IllegalStateException: recursive write in executePendingTransactions

I have AppCompatActivity

one that has 3 tabs using FragmentTabHost

. One of the tabs is used LocationServices

. I would like to have the best user experience possible:

If LocationService

disabled in Android system, but only if the user selects the tab that he needs Location

, I would like to display AlertDialog

so that the user can on Location

in system preferences.

I have a helper class that needs to do all of this and it works in 3 other places in my application. In these three places it works "right" in Activity

, but in this place it needs to work "inside" the Fragment

tab.

The problem is, if I have a line:

builder.enableAutoManage(activity, 0, this);

      

then builder.build()

throws an exception:IllegalStateException: Recursive entry to executePendingTransactions

Any idea how I can achieve my goal?

Here are some related code snippets:

public class CityPreferences extends AppCompatActivity {
    private FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
        mTabHost.addTab(
                mTabHost.newTabSpec("available_cities")
                        .setIndicator(getString(R.string.tab_all_cities))
                , AvailableCityFragment.class, null);
        mTabHost.addTab(
                mTabHost.newTabSpec("nearby_cities")
                        .setIndicator(getString(R.string.tab_nearby_cities))
                , NearbyCityFragment.class, null);
    }
}

      

Q NearbyCityFragment

I have this 1 line of code:

class NearbyCityFragment extends Fragment {
...
    LocationServiceHelper.getInstance().startOrDisplayDialog(getActivity());

      

(I tried it in the onAttach

, onStart

, onResume

)

And here's my helper function:

public class LocationServiceHelper implements
    GoogleApiClient.OnConnectionFailedListener,
    GoogleApiClient.ConnectionCallbacks {

public boolean startOrDisplayDialog(@NonNull final FragmentActivity activity) {
    final boolean servicesConnected = GooglePlayServicesHelper.checkOrDisplayDialog(activity);
    if (servicesConnected) {
        final boolean isEnabled = isLocationEnabledInSystem(activity);
        if (isEnabled) {
            if (null == mGoogleApiClient) {
                mContext = activity;
                mActivity = activity;
                final GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mContext)
                        .addApi(LocationServices.API)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this);

                // the next line seems to cause the problem:
                builder.enableAutoManage(activity, 0, this);

                mGoogleApiClient = builder
                        .build();
            }
            return start();
        } else {
            final Dialog dialog = getLocationDisabledDialog(activity);
            GooglePlayServicesHelper.showDialog(dialog, activity);
        }
    }
    return false;
}

      

And finally the exception:

06-10 10:23:04.831  26725-26725/com.fletech.android.redalert.debug E/AndroidRuntime๏น• FATAL EXCEPTION: main
    Process: com.fletech.android.redalert.debug, PID: 26725
    java.lang.IllegalStateException: Recursive entry to executePendingTransactions
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1473)
            at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
            at com.google.android.gms.common.api.g.a(Unknown Source)
            at com.google.android.gms.common.api.GoogleApiClient$Builder.gI(Unknown Source)
            at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source)
            at com.fletech.android.redalert.helper.LocationServiceHelper.startOrDisplayDialog(LocationServiceHelper.java:113)
            at com.fletech.android.redalert.city.NearbyCityFragment.onAttach(NearbyCityFragment.java:44)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:907)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

      

+3


source to share


1 answer


I believe that every time you enable auto-manager you should use a unique one clientId

. From the doc:



clientId

is a non-negative identifier for this client. Only one automatically managed client is allowed for each ID at any given time. To reuse an identifier, you must first call stopAutoManage(FragmentActivity)

on the previous client.

+3


source







All Articles