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)
source to share
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 callstopAutoManage(FragmentActivity)
on the previous client.
source to share